AQS 동기 화 구성 요소--ReentrantLock 과 자물쇠
Synchronized 와 ReentrantLock 의 공통점 과 차이 점
4.567917.재 입 성:둘 다 재 입 성 을 가진다
ReentrantLock 만 의 기능
@Slf4j
public class LockExample2 {
//
public static int clientTotal = 5000;
//
public static int threadTotal = 200;
public static int count = 0;
private final static Lock lock = new ReentrantLock();
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}", count);
}
private static void add() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
우선 private final static Lock lock=new ReentrantLock()을 사용 하여 얻 은 인 스 턴 스 를 설명 한 다음 사용 합 니 다.
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
잠 금 추가 와 잠 금 해제 작업 을 진행 합 니 다.
우 리 는 하나의 예 를 통 해 이 ReentrantReadWrite Lock 을 어떻게 사용 하 는 지 보고 있다.
@Slf4j
public class LockExample3 {
private final Map map = new TreeMap<>();
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
public Data get(String key) {
readLock.lock();
try {
return map.get(key);
} finally {
readLock.unlock();
}
}
public Set getAllKeys() {
readLock.lock();
try {
return map.keySet();
} finally {
readLock.unlock();
}
}
public Data put(String key, Data value) {
writeLock.lock();
try {
return map.put(key, value);
} finally {
readLock.unlock();
}
}
class Data {
}
}
private final ReentrantReadWriteLock=new ReentrantReadWriteLock()을 통 해 ReentrantReadWriteLock 을 설명 한 다음 private final Lock readLock=lock.readLock()private final Lock writeLock=lock.writeLock()읽 기와 쓰기 자 물 쇠 를 각각 가 져 옵 니 다.우 리 는 이 맵 을 읽 을 때 읽 기 자 물 쇠 를 넣 고 쓸 때 자 물 쇠 를 쓴다.그러나 여기 서 문제 가 있 는 것 은 이 자물쇠 가 비관 적 인 자물쇠 라 는 것 이다.즉,자 물 쇠 를 쓸 때 읽 기 자 물 쇠 를 가지 고 있 으 면 안 된다 는 것 이다.읽 기 동작 이 특히 많 을 때 자 물 쇠 를 계속 집행 하지 못 하 게 할 가능성 이 높다.
공식 적 인 예 를 들 어 배 워 보 겠 습 니 다.Stamped Lock.
import java.util.concurrent.locks.StampedLock;
public class LockExample4 {
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
//
double distanceFromOrigin() { // A read-only method
long stamp = sl.tryOptimisticRead(); //
double currentX = x, currentY = y; //
if (!sl.validate(stamp)) { // ?
stamp = sl.readLock(); // ,
try {
currentX = x; //
currentY = y; //
} finally {
sl.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
//
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) { // ,
long ws = sl.tryConvertToWriteLock(stamp); //
if (ws != 0L) { //
stamp = ws; //
x = newX; //
y = newY; //
break;
} else { //
sl.unlockRead(stamp); //
stamp = sl.writeLock(); //
}
}
} finally {
sl.unlock(stamp); //
}
}
}
}
앞 에 있 는 안 을 Stamped Lock 으로 바 꿔 보도 록 하 겠 습 니 다.
@Slf4j
public class LockExample5 {
//
public static int clientTotal = 5000;
//
public static int threadTotal = 200;
public static int count = 0;
private final static StampedLock lock = new StampedLock();
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}", count);
}
private static void add() {
long stamp = lock.writeLock();
try {
count++;
} finally {
lock.unlock(stamp);
}
}
}
여기 가 예전 과 다른 점 이 바로...
long stamp = lock.writeLock();
try {
count++;
} finally {
lock.unlock(stamp);
}
자 물 쇠 를 추가 하면 값 을 되 돌려 줍 니 다.자 물 쇠 를 풀 때 이 값 을 입력 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
java. util. concurrent 패키지 의 해체@Date 2019-7-8 11:25*/public class BlockingQueueExample {public static void main(String[] args) {BlockingQueue blockingQ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.