배타적 접근, 비배타적 접근, 낙관적 읽기 등의 기능을 제공하는 Lock 클래스.
각각 writeLock, readLock, tryOptimisticRead 메소드가 속한다.
자주 사용할 것 같은 메소드 위주로 정리했다.
void unlock(long stamp)
void unlockRead(long stamp)
void unlockWrtie(long stamp)
락을 해제한다. 락을 걸 때 반환받은 스탬프를 파라미터로 제공하면 된다.
long writeLock()
배타적 락을 건다. 반환값은 스탬프이므로 해제 시 반드시 필요한 값이다.
해당 락이 수행된 경우, 읽기/쓰기가 불가능해진다.
long readLock()
비배타적 락을 건다.
해당 락을 수행한 경우, writeLock 요청만이 Lock이 반환될 때까지 대기하게 된다.
long tryOptimisticRead()
낙관적 읽기를 수행하기 위해 사용되는 메소드. 0 또는 스탬프 값을 반환한다.
스탬프를 반환하나 락을 수행하지 않는다. 아래 메소드에서 이어서 설명.
boolean validate(long stamp)
현재 락의 스탬프가 주어진 스탬프와 동일한지 확인하는 스탬프. 배타적 락이 수행되지 않았다면 참, 아니라면 거짓을 반환한다. 0이 입력된다면 무조건 거짓을 반환한다.
위 tryOptimisticRead() 메소드로 스탬프를 얻은 뒤 값을 읽고, validate를 통해 스탬프가 변경되었는지 확인하는 작업이 필요하다.
만약 배타적 락이 수행되지 않았다면, 가져온 값을 계속 사용하면 된다.
만약 배타적 락이 수행되었다면, readLock으로 락을 걸고 값을 가져오면 된다.
이는 락으로 인한 성능 저하를 최소화하기 위해서 락을 걸지 않고 값을 읽는 것을 수행하는 것이다.
아래와 같이 사용할 수 있다;
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);
} // java 1.8 javadoc StampedLock 예시 코드
// a read-only method
// upgrade from optimistic read to read lock
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead(); // 낙관적 읽기를 위한 스탬프
try {
retryHoldingLock: for (;; stamp = sl.readLock()) {
if (stamp == 0L) // stamp == 0이라면 락 획득 시도
continue retryHoldingLock;
// possibly racy reads
double currentX = x; // 값 읽기
double currentY = y;
if (!sl.validate(stamp)) // 배타적 잠금이 수행되었다면 락 획득 시도
continue retryHoldingLock;
return Math.hypot(currentX, currentY); // 결과 반환
}
} finally {
if (StampedLock.isReadLockStamp(stamp)) // 스탬프가 readLock 스탬프라면
sl.unlockRead(stamp); // 락 해제
}
} // java 21 javadoc StampedLock 예시 코드
long tryConvertToReadLock(long stamp)
long tryConvertToWriteLock(long stamp)
long tryConvertToOptimisticRead(long stamp)
스탬프를 바탕으로 락의 상태를 변경한다. 0 또는 스탬프가 반환된다. 0은 실패를 의미.
long tryReadLock()
long tryWriteLock()
락 획득을 대기하지 않고 즉시 스탬프 또는 0을 반환한다. 대기가 필요하다면 readLock(), writeLock()을 사용해야 한다.
참고
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/StampedLock.html
'Java > JDK' 카테고리의 다른 글
| JDK를 공부하는 법을 알아보자 (0) | 2025.05.09 |
|---|