원문 URL : http://tutorials.jenkov.com/java-concurrency/blocking-queues.html
블로킹 큐란 특정 상황에 쓰레드를 대기하도록 하는 큐이다. 큐에서 엘레멘트를 빼려고 시도했는데(디큐) 큐가 비어있다거나, 큐에 엘레멘트를 넣으려 했는데(인큐) 큐에 넣을 수 있는 공간이 없다거나 할 때 디큐/인큐 호출 쓰레드를 대기하도록 한다. 비어있는 큐에서 엘레멘트를 빼려고 시도하는 쓰레드의 대기 상태는 다른 쓰레드가 이 큐에 엘레멘트를 넣을 때까지 지속된다. 꽉 찬 큐에 엘레멘트를 넣으려 시도하는 쓰레드의 대기 상태는 다른 쓰레드가 큐에서 엘레멘트를 빼거나 큐를 정리하여(clean) 큐의 공간이 확보될 때까지 지속된다.
아래는 한 블로킹 큐를 둔 두 쓰레드의 상호 동작을 보여준다.
Java 5 는 java.util.concurrent 패키지에 블로킹 큐를 포함한다. 이 블로킹 큐 클래스에 대한 내용은 java.util.concurrent.BlockingQueue(원문) 튜토리얼에서 볼 수 있다. Java 5 가 블로킹 큐 구현체를 제공하긴 하지만, 역시 그 기반 이론을 아는 일은 가치가 있다.
블로킹 큐 구현
블로킹 큐의 구현은 바운디드 세마포어와 유사하다. 간단한 블로킹 큐 구현을 보자.
public class BlockingQueue {
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
if(this.queue.size() == 0) {
notifyAll();
}
this.queue.add(item);
}
public synchronized Object dequeue()
throws InterruptedException{
while(this.queue.size() == 0){
wait();
}
if(this.queue.size() == this.limit){
notifyAll();
}
return this.queue.remove(0);
}
}
큐 크기가 크기 제한에 다다르면 enqueue() 와 dequeue() 에서 notifyAll() 이 호출된다. 큐 크기가 제한에 다다르지 않은 상태로 enqueue() 나 dequeue() 가 호출되면 쓰레드는 대기하지 않는다.
'Java > Concurrency' 카테고리의 다른 글
컴페어 스왑(Compare and Swap) (0) | 2017.05.24 |
---|---|
쓰레드 풀(Thread Pools) (0) | 2017.05.22 |
세마포어(Semophores) (0) | 2017.05.22 |
재진입 락아웃(Reentrance Lockout) (0) | 2017.05.21 |
읽기/쓰기 락(Read/Write Locks in Java) (0) | 2017.05.16 |