Java ReentrantLock 클래스 - 명시적으로 잠금 획득
명시적으로 잠금 획득 – ReentrantLock 클래스
public void lock()
public void unlock()
synchronized
블록에 의한 동기화는 어플리케이션 개발자가 락의 획득/해제를 의식하지 않아도 되기 때문에 “암묵적인 락"이라고 한다. 반대로 메서드를 통해서 “명시적으로 락"을 걸거나 해제하고 싶은 경우가 있다. 이런 경우에는 ReentrantLock
클래스(java.util.concurrent.locks
패키지)를 이용한다.
ReentrantLock
클래스에서는 lock
메서드로 명시적으로 락을 건 후에는 unlock
메서드로 해제해줘야 한다.
다음은 synchronized
한정자 사용한 예제(increment 메서드)을 ReentrantLock 클래스에서 다시 작성한 것이다.
LockSample.java
package com.devkuma.basic.thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockSample {
private int count;
private final Lock lock = new ReentrantLock();
public static void main(String[] args) {
LockSample ls = new LockSample();
ls.execute();
}
public void execute() {
final int THREAD_MAX = 300000;
Thread[] ts = new Thread[THREAD_MAX];
for (int i = 0; i < THREAD_MAX; i++) {
ts[i] = new Thread(new MyThread(this));
ts[i].start();
}
for (int i = 0; i < THREAD_MAX; i++) {
try {
ts[i].join();
} catch (InterruptedException e) {
System.out.println(e);
}
}
System.out.println(count);
}
public void increment() {
lock.lock();
try {
this.count++;
} finally {
lock.unlock();
}
}
private static class MyThread implements Runnable {
private LockSample _counter;
public MyThread(LockSample counter) {
this._counter = counter;
}
@Override
public void run() {
_counter.increment();
}
}
}
실행 결과:
300000
ReentrantLock
클래스에서 lock
메서드를 사용을 하게 되면, 그 직후에 try
블록으로 감싸야 한다. 이는 처리 중에 예기치 않은 예외가 발생한 경우에도 finally
절에서 unlock
메서드가 호출되는 것을 보장하기 위해서 이다.
최종 수정 : 2022-09-24