2012-05-14 5 views
1

아래의 의사 코드에서 나는 주 스레드에서 영원히 호출되는 poll() 함수를 가지고 있습니다. poll()sleep() 문없이이 작업을 수행하면 다른 스레드가 1 분에 2-3 개의 항목 만 대기열에 추가됩니다. 이것은 폴링이 put() 성명을 차단한다는 것을 의미합니까?폴링이 LinkedBlockingQueue에서 다른 작업을 차단합니까?

이 문제를 어떻게 해결할 수 있습니까?

public class Test extends Thread{ 
    private LinkedBlockingQueue<Object> queue = null; 

    Test(){ 
     queue = new LinkedBlockingQueue<Object>(10); 
    } 

    public void run(){ 
     // Do stuff, get incoming object from network 
     queue.put(o); 
    } 

    public Object poll(){ 
     Object o = queue.poll(); 
     sleep(1000); 
     return o; 
    } 
} 

답변

11

이 풋() 문이 폴링 블록을 의미 하는가?

아니, LinkedBlockingQueue 완전히 재진입하고 poll() 방법은 put()을 차단하지 않습니다. 그러나 poll() 메서드는 즉시 반환합니다. 아마도 queue.take()을 사용해야하는데, 대기열이 비어 있으면 null을 반환하는 대신 대기열에 항목이있을 때까지 대기합니다.

// wait for there to be an object in the queue 
    Object o = queue.take(); 
    // no sleep necessary 
    return o; 

는 10 개 항목의 제약 블록 큐를 구성하고 있기 때문에, 나는 주는 sleep()에 차단하고 큐가 다음 채우고 프로그램 저하되는 것 같아요. poll()null 인 경우에만 sleep을 입력하고 잠자기 시간을 줄여야합니다.

편집 :은 코멘트에서 언급 @JohnVint으로, 다른 대안은 항목이 기간 동안 큐에 추가 될 때까지 기다립니다 타이머가 만료되면 null를 반환 할 poll(long, TimeUnit) 방법을 사용하는 것입니다. 그것은 대기열에있는 어떤 것을 기다리는 더 깨끗한 방법입니다.

// wait for 1000ms for there to be an object in the queue 
    Object o = queue.poll(1000, TimeUnit.MILLISECONDS); 
    // no sleep necessary 
    return o; 
+0

+1 - 좋은 전화 'take()' –

+0

예, 저의 첫 번째 아이디어였습니다. 하지만 take()를 사용하면 대기열이 비어 있으면 내 mainthread가 차단됩니다. 나는 그 스레드에서 다른 것들도하고 싶다. – fibera

+2

@fibera 그런 기능에 대해'public E poll (long timeout, TimeUnit unit) throws InterruptedException'을 살펴보십시오. 클리너와 더 정확한 다음 '잠'. –