<aside> 💡 synchronized와 같이 동기화를 제공하지만, 동기화의 시작과 끝을 지정할 수 있는 객체

</aside>

개요


기존의 synchronized는 메서드 혹은 블록내에 작성을 할 수 있으며 잠금과 반환이 자동으로 이뤄진다.

public synchronized void order(){ ... } //메서드가 선언된 객체에 대한 잠금및 반환이 자동이다.

public void order(){
		synchronized(products) { ... } //자원에 대한 잠금과 반환이 자동으로 이뤄진다.
}

하지만, 상황에따라 이런 잠금의 시작과 잠금의 종료를 내가 임의로 정해야 하는 경우가 생기고 이런 경우 사용하게 되는 상호베타적 락이 이 Reentrant Lock으로 JDK1.5에서 추가되었으며 java.util.concurrent.locks 패키지에서 제공되고 있다.

사용법


사용법은 간단하다. lock , unlock 메서드를 통해 잠금(Lock)의 시작과 종료를 명시적으로 작성해줄 수 있다.

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

⇒ ReentrantLock 참조변수는 왠만해서는 private final로 선언해주자.

⇒ unlock()은 작업이 끝나고 무조건 실행되어 잠금을 풀어줘야 하기때문에 finally 블록에 작성하여 try 블록 내에서 오류가 생기더라도 unlock()은 실행될 수 있도록 한다.

기존 쓰레드에는 특정 쓰레드에서 객체의 락을 너무 오랫동안 가지지 않도록 하기 위해서 만든 메서드들이 있는데,

이를 이용해 스레드가 로직 진행을 더 이상 하지 못하고 대기해야하는 상황일 때 wait()을 호출해 락을 반납 후 기다리도록 할 수 있다. 그 밖에 notify()를 이용해 작업을 진행할 수 있는 상황에서 다시 락을 얻어 진행(재진입)할수도 있다. ReentLock에서는 이런 메서드들을 그대로 사용할 수는 없고 다음과 같은 메서드를 제공한다.