자바의 모든 객체에는 모니터가 있다. synchronized는 이 모니터락을 이용한다.
하지만 락 대기시간을 설정못하고 락 획득 순서가 보장되지 않는 단점이 있다.
Lock인터페이스는 이런 문제를 해결해준다 대표적인 구현체로는 ReentrantLock이 있다.
ReentrantLock은 모니터를 이용하는게 아니라 자체적인 락을 이용한다.
오래 기다린 스레드가 먼저 실행되는 공정모드와 비공정모드 선택가능하다
비공정 모드는 락 획득 속도가 빠르고 선점 가능하며 기아 가능성이 있다.
공정 모드는 락 획득 속도가 느리고 기아 현상이 일어나지 않는다. 락 획득 순서가 보장된다.
비공정 모드는 내부가 큐로 구현되어있어 대부분 상황에는 순서대로 시행된다 하지만 경합이 심해 새로운 스레드가 들어오면 가끔 선점이 일어나긴한다 공정 모드는 무조건적인 순서가 필요할 때 사용한다.
ReentrantLock의 unlock()을 시행하면 LockSupoort.unpark(thread)가 시행되면서 대기 큐의 스레드를 WAITING또는 TIMED_WATING에서 RUNNABLE로 만들고 깨어난 스레드는 락을 시도한다. 락을 획득하지 못하면 다시 대기한다.
volatile을 사용하지 않아도 Lock을 사용하면 메모리 가시성 문제가 해결된다. 자바 메모리 모델의 happens before에서 자바의 동기화 기법을 사용하면 메모리 가시성 문제가 해결된다고 말한다.