LOCKS(락)
java concurrency in practice 를 읽다보면 락 클래스가 어디에 사용되는지 자세히 설명해 놓았다. 본문을 참고로 왜 명시적인 락 클래스를 따로 만들었는지 요약해보겠다.
암묵적인 락 기능이 있는데 왜 명시적인 락 클래스를 따로 만들었을까? 암묵적인 락(synchronized)로 수용할 수 없는 문제(기능적으로 제한되는 경우)가 발생된다.

ex> 락을 확보하고자 대기하고 있는 쓰레드에 인터럽트를 걸거나, 대기 상태에 들어가지 않으면서 락을 확보하는 방법

성능
- 자바 5.0 에서는 ReentrantLock 은 암묵적인 락에 비해 훨씬 낳은 경쟁 성능(contended performance)을 보여준다.

자바 6 의 암묵적인 락은 개선되어 좀더 낳은 성능을 보임

- 블록 동기화 기능으로 synchronized 보다 진보된 능력을 제공한다. 락 타임아웃, 락당 복수의 조건 변수, 읽기/쓰기 락, 락 대기중인 스레드의 인터럽트 지원

- 전형적인 락 사용 패턴
 락 획득 -> 보호된 리소스에 엑세스 -> 락 해제
Lock lock = new ReentrantLock();
// 락 획득
lock.lock();
try {
 // critical section
} finally {
 // 획 해제
 lock.unlock();
}

- lockInterruptibly()
대기중인 스레드에 인터럽트할 수 있게 해준다. interrupt() 가 호출되면 대기 상태가 입터럽트되며 InterruptedException 이 던져진다.

락 획득이 실패할 경우에 unlock() 이 호출되면 안되기 때문에 try-finally, try-catch 로 나눠서 예외를 처리.
Lock lock = new ReentrantLock(); 

// 락을 인터럽트 시킬수 있다.
lock.lockInterruptibly();

try {
    // critical section
} finally {
    // 획 해제
    lock.unlock();
}

- tryLock()
 lock.tryLock()
  : 락이 가용 상태가 아닐 경우 즉시 실패 처림 됨.

 lock.tryLock(second, TimeUnit.SECOND)
  : 3초 동안 락 획득을 시도하고 락을 얻을 수 없으면 false를 반환하여 락을 얻을 수 없음을 알린다.
Lock lock = new ReentrantLock(); 

if(lock.tryLock()) return;

try {
    // critical section
} finally {
    // 획 해제
    lock.unlock();
}

- java.util.concurrent.locks 의 Lock 인터페이스
 1. ReentrantLock
  : 일반적으로 사용되는 락 (synchronized 랑 비슷한 유형일듯)
 
 2. ReentrantReadWriteLock 의 ReadLock , WriteLock
  : 읽고/쓰기 의 사용 비율에 따라 골라서 사용함
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock  = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();

ReentractLock 과 동일하게 사용.


Posted by 짱가쟁이