2013-04-09 5 views
1

내가 BlockingQueue 있고 일부 스레드 take() 호출됩니다 있지만 큐가 비어있는 순간. 그리고 미래에 새로운 요소가 대기열에 나타나지 않는다는 것을 어떻게 든 알고 있다고 가정 해 봅니다. take() 호출 된 스레드를 대기 상태에서 해제하려면 어떻게해야합니까? 감사!BlockingQueue 및 대기 스레드 해제 대기

public Order getFromProcessedOrders() throws InterruptedException { 
    return processedOrders.take(); 
} 

및 processedOrders BlockingQueue를

+0

당신이 우리에게 u는 이미 만들어진 코드를 보여줄 것인가를? – DRastislav

+1

http://stackoverflow.com/questions/5378391/closing-a-blocking-queue – Edmondo1984

+1

잠시만 기다려주십시오 :) –

답변

2

-

BlockingQueue를 본질적 항목이 더 이상 추가되지 않는 것을 나타 내기 위해서 "닫기"또는 "종료"작업의 모든 종류를 지원하지 않습니다. 이러한 기능의 필요성과 사용법은 구현에 따라 달라지는 경향이 있습니다. 예를 들어 생산자가 스트림 끝 또는 독 오브젝트를 삽입하는 일반적인 방법은 소비자가 을 가져갈 때 그에 따라 해석됩니다.

당신은 그것을 차단 된 스레드 중단해야 -

public void run() { 
        //noinspection InfiniteLoopStatement 
        while (true) { 
            try { 
                Thread.sleep(millisecondsToSleep); 
                if (!kitchen.processedOrdersEmpty()) { 
                    Order processedOrder = kitchen.getFromProcessedOrders(); 
                    kitchen.printMessage("took order#" + processedOrder.getOrderNumber()); 
                    Thread.sleep(millisecondsToServe); 
                    kitchen.printMessage("served order#" + processedOrder.getOrderNumber()); 
                } else { 
                    int currentRandom = getNextRandom(); 
                    if (currentRandom <= 10) { 
                        Order newOrder = new Order(kitchen.getLastOrderNumber()); 
                        kitchen.puIntoUnprocessedOrders(newOrder); 
                        kitchen.printMessage("generated new order#" + newOrder.getOrderNumber()); 
                    } else { 
                        Thread.sleep(millisecondsToSleep); 
                    } 
                } 
            } catch (InterruptedException ex) { 
       //... handle ... 
      }catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
2

1) 테이크은()

2를 실행하는 스레드를 중단 할 수 있습니다)입니다 : kitchen.getFromProcessedOrders() 동일이

public void run() { 
     //noinspection InfiniteLoopStatement 
     while (true) { 
      try { 
       Thread.sleep(millisecondsToSleep); 
       if (!kitchen.processedOrdersEmpty()) { 
        Order processedOrder = kitchen.getFromProcessedOrders(); 
        kitchen.printMessage("took order#" + processedOrder.getOrderNumber()); 
        Thread.sleep(millisecondsToServe); 
        kitchen.printMessage("served order#" + processedOrder.getOrderNumber()); 
       } else { 
        int currentRandom = getNextRandom(); 
        if (currentRandom <= 10) { 
         Order newOrder = new Order(kitchen.getLastOrderNumber()); 
         kitchen.puIntoUnprocessedOrders(newOrder); 
         kitchen.printMessage("generated new order#" + newOrder.getOrderNumber()); 
        } else { 
         Thread.sleep(millisecondsToSleep); 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

특수 객체를 끝의 신호로 대기열에 넣을 수 있습니다. 스레드가 특수 오브젝트 (END)를 얻으면 스레드를 다시 넣고 종료하므로 대기중인 다른 스레드도 END를 얻습니다.

+0

3) 스레드가 종료되어야 함을 나타내는 휘발성 값을 설정합니다. – jontro

+0

@jontro 세 개의 스레드가 크기가 2 인 큐에서 가져 오려고하면 그다지 도움이되지 않습니다. 세 번째 스레드는 무기한으로 대기합니다. –

+0

END가있는 스레드는 다시 넣고 종료 할 수 있습니다. –

0

new String("##EOQ##")과 같은 더미 레코드를 추가하여 대기열 종료를 나타내며 소비자 스레드를 중지 할 수 있습니다. java docs에 따르면