이 글은 원 저자 Jakob Jenkov의 허가로 포스팅된 번역물이다.

원문 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

+ Recent posts