문제

나는 가고 싶다 SynchronousQueue 하나의 스레드에서 요소를 삽입하는 곳 put(), 따라서 요소가 다른 스레드에서 가져올 때까지 입력이 차단됩니다.

다른 스레드에서는 많은 계산을 수행하고 때때로 요소가 이미 사용 가능한지 확인하고 소비하려고합니다. 그러나 그것은 것 같습니다 isEmpty() 다른 스레드가 대기하는 경우에도 항상 진실을 반환합니다. put() 전화.

지구상에서 어떻게 가능합니까? 다음은 샘플 코드입니다.

@Test
public void testQueue() throws InterruptedException {
    final BlockingQueue<Integer> queue = new SynchronousQueue<Integer>();

    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                if (!queue.isEmpty()) {
                    try {
                        queue.take();
                        System.out.println("taken!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // do useful computations here (busy wait)
            }
        }
    });
    t.start();

    queue.put(1234);
    // this point is never reached!
    System.out.println("hello");
}

편집하다: ISEMPTY () 나 PEEK () 작업도 없으며 Poll ()을 사용할 필요가 없습니다. 감사!

도움이 되었습니까?

해결책

에서 http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/synchronousqueue.html#put(e) :

비었다
공개 부울 isempty ()
항상 진실을 반환합니다. 동기식에는 내부 용량이 없습니다.

(이것에 대해 자세히 살펴 보지 않았지만 어느 쪽도 살펴보고 싶을 수도 있습니다. 투표 또는 가져가다 대신에)

다른 팁

Tim의 답변 외에도 소비자 스레드에서 아무것도하지 않고 꽉 루프로 Isempty ()를 계속 호출합니다. OS에 유용한 일이있을 때까지 OS를 실행하지 말라고 요청하는 대신 소비자 스레드는 지속적으로 바쁘다. Isempty가 올바르게 작동하더라도 프로듀서 스레드는 거의 기회를 얻지 못할 것입니다.

(isempty ()가 작동했거나 poll ()를 사용하여 전환 한 경우) 큐가 비어있을 때 소비자가 약간의 잠을 자면서 생산자에게 달리기 기회를 주거나 (바람직하게는) (바람직하게는) isempty () 테스트를 테스트하고 폴링 대신 테이크 () 내부의 뮤 테스의 스레드 블록을 현명한 방식으로 테스트하십시오.

코드는 여론 조사를 시도하는 것처럼 보입니다. 왜 poll () 메소드를 호출하지 않으시겠습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top