PHpullh

JAVA · 비동기/동시성

ReentrantLock

synchronized보다 유연한 ReentrantLock의 활용법입니다.

비동기/동시성고급ReentrantLockLocktryLock동기화

핵심 설명

synchronized보다 유연한 ReentrantLock의 활용법입니다.

Java code

import java.util.concurrent.locks.*;
import java.util.concurrent.*;

public class ReentrantLockDemo {
    private final ReentrantLock lock = new ReentrantLock(true); // 공정성
    private int balance = 1000;

    void deposit(int amount) {
        lock.lock();
        try {
            balance += amount;
            System.out.printf("입금 %d -> 잔액 %d%n", amount, balance);
        } finally {
            lock.unlock(); // 반드시 finally에서!
        }
    }

    boolean tryWithdraw(int amount) {
        // tryLock — 논블로킹 시도
        if (lock.tryLock()) {
            try {
                if (balance >= amount) {
                    balance -= amount;
                    System.out.printf("출금 %d -> 잔액 %d%n", amount, balance);
                    return true;
                }
            } finally {
                lock.unlock();
            }
        }
        return false;
    }

    boolean timedWithdraw(int amount) throws InterruptedException {
        // 타임아웃 있는 시도
        if (lock.tryLock(1, TimeUnit.SECONDS)) {
            try {
                balance -= amount;
                return true;
            } finally {
                lock.unlock();
            }
        }
        return false;
    }

    public static void main(String[] args) {
        var account = new ReentrantLockDemo();
        account.deposit(500);
        account.tryWithdraw(200);
        System.out.println("대기 스레드: " + account.lock.getQueueLength());
    }
}

학습 팁

ReentrantLock(true)로 공정(fair) 모드를 켜면 대기 순서가 보장됩니다. 다만 처리량이 약간 감소합니다.

주의할 점

lock()unlock()finally에서 호출하지 않으면 데드락이 발생합니다. 이것은 synchronized 대비 단점입니다.

자주 묻는 질문

ReentrantLock란 무엇인가요?

synchronized 보다 유연한 ReentrantLock 의 활용법입니다.

ReentrantLock 학습 시 주의할 점은 무엇인가요?

lock() 후 unlock() 을 finally 에서 호출하지 않으면 데드락이 발생합니다. 이것은 synchronized 대비 단점입니다.