2015-02-01 5 views
1

내가은 - 왜) (이 통지하지

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); 
    } 

} 

나의 이해는 이것이다 그것을 이해하려고 노력 온라인이 경계 큐 코드를 통과했다 : 더 이상 항목이없는 경우

  1. 대기열에서 아무 것도 대기열에서 제외 할 수 없으므로 wait()를 호출합니다.
  2. 대기열에 항목 수가 최대 인 경우 대기열을 지정할 수 없으므로 wait()를 호출합니다.
  3. 공간이 있으면 (큐의 일부 요소) 우리는 또한 디큐
  4. 뿐만 아니라 대기열 호출 할 수 있습니다 우리의 notifyAll() 그래서()의 모든 생산자와 소비자는

깨워 그러나 우리가 대기를 호출 요청에 일어나는 것을 . 그들은 notifyAll() 호출에서만 통지를 받습니까? 대기열에 공간이 생기 자마자 통지를받지 못하는 이유는 무엇입니까?

+0

단지 notifyAll()을 볼 수 있지만 알리지는 않습니다. 어떻게 통지를 받습니까? –

+1

'notifyAll'은 무엇이라고 생각하십니까? –

+0

notifyAll()은 요소가 더 이상 없을 때만 enqueue에서 호출되고 max 요소가있을 때 dequeue에서 호출됩니다. 내 질문은 바로 그 것이다. 왜 이러한 제한을 기다리는 중입니까? 가능한 한 빨리 알려주지 않는 이유는 무엇입니까? –

답변

2

빈 큐에 추가 할 때만 알릴 필요가 있습니다. 비 큐업자가 빈 큐에서만 대기하기 때문입니다.

마찬가지로 대기열에서 대기열에서 대기열에서 대기열에 들어갈 때만 대기열에 대기하기 때문에 알리면됩니다.

+0

아, 이제 이해가가는 것 같아요. 감사 –

0

두 사소한 코드를 이해하기위한주의 사항 :

  1. 스레드는 두 notifyAll가 마지막 줄 이외의 장소에 배치 할 수 있습니다 이유입니다, 깨어 전에 잠금을 획득해야합니다.
  2. 대기 외에도 대기열이 있습니다. 조건에 대기중인 스레드가 없으면 대기열에있는 모든 스레드가 대기열에 잠겨 잠금을 가져옵니다. 따라서 큐가 가득 찼거나 비었을 때 notifyAll 코드 만 수행합니다.