[java] 쓰레드의 동기화 방법: Lock과 Condition

쓰레드를 사용하여 병렬 처리를 구현할 때, 여러 쓰레드가 공유 자원에 동시에 접근할 수 있는데, 이때 동기화가 필요합니다. 쓰레드 동기화를 위해 LockCondition을 사용하는 방법을 알아보겠습니다.

1. Lock과 Condition 소개

자바에서는 Lock 인터페이스와 Condition 인터페이스를 제공하여 쓰레드의 동기화를 지원합니다.

2. Lock을 이용한 동기화

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SynchronizedCounter {
    private int count = 0;
    private Lock lock = new ReentrantLock();

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

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

위 코드에서 ReentrantLock을 사용하여 동기화를 구현했습니다. lock()unlock() 메서드를 사용하여 임계 영역을 설정하고 해제합니다.

3. Condition을 이용한 동기화

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedBuffer {
    final Lock lock = new ReentrantLock();
    final Condition notFull = lock.newCondition();
    final Condition notEmpty = lock.newCondition();

    final Object[] items = new Object[100];
    int putptr, takeptr, count;

    public void put(Object x) throws InterruptedException {
        lock.lock();
        try {
            while (count == items.length) {
                notFull.await();
            }
            items[putptr] = x;
            if (++putptr == items.length) putptr = 0;
            ++count;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await();
            }
            Object x = items[takeptr];
            if (++takeptr == items.length) takeptr = 0;
            --count;
            notFull.signal();
            return x;
        } finally {
            lock.unlock();
        }
    }
}

위 코드는 Condition을 사용하여 생성자에서 Lock으로부터 생성된 Condition 인스턴스를 초기화하고, await()signal()을 사용하여 쓰레드 간의 통신을 구현한 예제입니다.

결론

쓰레드의 동기화를 위해 LockCondition을 사용하는 방법에 대해 알아보았습니다. LockCondition을 사용하면 synchronized 키워드만으로는 구현하기 어려운 다양한 동기화 제어가 가능해집니다.

이러한 기능을 사용하여 적절하게 동기화된 쓰레드를 구현하여 안정적이고 효율적인 병렬 처리를 할 수 있습니다.

자세한 내용은 Oracle Java Documentation를 참고하세요.