[java] 스레드 간의 동기화 방법 비교

자바에서는 멀티스레딩을 지원하기 위해 동기화 기법을 사용할 수 있습니다. 동기화는 여러 개의 스레드가 작업하는 동안 데이터의 일관성을 보장하기 위한 중요한 개념입니다. 이러한 동기화를 위해 여러 가지 방법이 제공되며 이번 글에서는 가장 널리 사용되는 세 가지 동기화 방법에 대해 알아보겠습니다.

1. synchronized 키워드

synchronized 키워드는 가장 기본적인 동기화 방법입니다. 메소드나 블록에 synchronized 키워드를 붙이면 해당 메소드 또는 블록 내에서는 단 하나의 스레드만이 실행될 수 있습니다. 이를 통해 데이터의 일관성을 보장할 수 있습니다. 예제 코드는 다음과 같습니다:

public class SynchronizationExample {
    private int counter = 0;

    public synchronized void increment() {
        counter++;
    }

    public synchronized void decrement() {
        counter--;
    }

    public int getCounter() {
        return counter;
    }
}

위의 예제에서는 incrementdecrement 메소드에 synchronized 키워드를 사용하여 동기화를 수행하고 있습니다.

2. ReentrantLock 클래스

ReentrantLock 클래스는 다른 스레드의 접근을 막고 단 하나의 스레드만 실행될 수 있도록 제어하는 동기화 방법입니다. ReentrantLock 객체를 생성하고 lock() 메소드로 락을 확보한 후 작업을 완료하면 unlock() 메소드로 락을 풀어야 합니다.

public class LockExample {
    private int counter = 0;
    private Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            counter++;
        } finally {
            lock.unlock();
        }
    }

    public void decrement() {
        lock.lock();
        try {
            counter--;
        } finally {
            lock.unlock();
        }
    }

    public int getCounter() {
        return counter;
    }
}

3. AtomicInteger 클래스

AtomicInteger 클래스는 원자적 연산(Atomic operation)을 수행하는 동기화 방법입니다. AtomicInteger 객체를 사용하면 별도의 동기화 메커니즘을 사용하지 않고 스레드 간에 안전하게 값을 증가 또는 감소시킬 수 있습니다.

public class AtomicExample {
    private AtomicInteger counter = new AtomicInteger(0);

    public void increment() {
        counter.incrementAndGet();
    }

    public void decrement() {
        counter.decrementAndGet();
    }

    public int getCounter() {
        return counter.get();
    }
}

동기화 방법 비교

각 동기화 방법은 장단점을 가지고 있으며, 상황에 따라 적합한 방법을 선택해야 합니다. synchronized 키워드는 사용하기 간편하지만 성능이 좋지 않을 수 있습니다. ReentrantLock은 세밀한 제어가 가능하며 조건과 함께 사용될 때 유용합니다. AtomicInteger는 대량의 스레드가 접근하는 경우 더 좋은 성능을 보장합니다.

이러한 동기화 방법들을 비교하고 상황에 맞게 적용하는 것이 중요합니다. 자신의 상황에 가장 적합한 방법을 선택하여 스레드 간의 동기화를 적절하게 처리해야 합니다.

참고자료