728x90
반응형
ReentrantLock 은 syncronized 보다 유연한 동기화 도구이다.
세밀한 제어가 간으하며, 인터럽트 처리를 지원한다. 또한 락 상태 확인이 가능하다.
ReentrantLock
- 같은 스레드가 락을 여러 번 획득 가능하며, 획득 횟수만큼 해제 필요
- ReentrantLock(true) 로 공정모드 설정. 대기 순서 보장(성능 저하 가능)
- Condition 객체로 특정 조건 기다림
- tryLock(long, TimeUnit) 으로 락 획득 시간 제한 가능
- 세밀한 제어 가능하며 인터럽트 처리를 지원
- 코드 복잡도가 증가하며, unlock() 메서드 누락 시 데드락 위험
public class LockCounter {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count ++;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
LockCounter counter = new LockCounter();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final count: " + counter.getCount());
}
}
tryLock() : 락을 즉시 획득 시도
public void tryIncrement() {
if (lock.tryLock()) {
try {
count++;
System.out.println("증가 " + Thread.currentThread().getName());
} finally {
lock.unlock();
}
} else {
// 락 획득 실패 시 대체 작업 가능
System.out.println("락 획득 시도 실패 " + Thread.currentThread().getName());
}
}
tryLock(long, TimeUnit) : 타임아웃 설정 가능
public void timedIncrement() throws InterruptedException {
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try {
count++;
System.out.println("Incremented after waiting");
} finally {
lock.unlock();
}
} else {
System.out.println("Timeout: Lock not acquired");
}
}
Condition : 조건 대기
public class ConditionExample {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void incrementAndWait() throws InterruptedException {
lock.lock();
try {
count++;
System.out.println("Count: " + count);
condition.await(); // 락 해제하고 대기
System.out.println("락 해제, 계속 진행");
} finally {
lock.unlock();
}
}
public void signal() {
lock.lock();
try {
condition.signal(); // 대기 중인 스레드 깨움
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
ConditionExample example = new ConditionExample();
Thread t1 = new Thread(() -> {
try {
example.incrementAndWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
System.out.println("Thread.sleep 1초 발생");
Thread.sleep(1000);
example.signal();
t1.join();
}
}
//결과값
Thread.sleep 1초 발생
Count: 1
락 해제, 계속 진행
728x90
반응형
'Language > JAVA' 카테고리의 다른 글
[자바 멀티스레딩] 자바 동시성 고급: ConcurrentHashMap 사용법 (0) | 2025.04.01 |
---|---|
[자바 멀티스레딩] 자바 동시성 고급: CountDownLatch 사용법 (0) | 2025.03.31 |
[자바 멀티스레딩] 동시성 제어: volatile 사용법 (0) | 2025.03.28 |
[자바 멀티스레딩] 동기화: synchronized 과 AtomicInteger 사용법 (0) | 2025.03.28 |
[자바 멀티스레딩] 스레드 풀: ExecutorService 사용법 (0) | 2025.03.27 |
댓글