2016-07-17 3 views
1

put()을 사용하여 스레드에 의해 채워지는 BlockingQueue가 있습니다. 하지만 BlockingQueue를 take()하는 방법에 대해서는 혼란 스럽다. 현재 다음과 같이 구현했습니다.Java BlockingQueue while() while 루프

String link; 
try { 
    while(!(link = links.take()).isEmpty()) { 
     System.out.println(link); 
    } 
} catch(InterruptedException ex) { 
    ex.printStackTrace(); 
} 

맞습니까? 조건문 안에 있지 않으면 큐를 반복하고 문자열 변수를 어떻게 할당 할 수 있습니까?

답변

1

정확하게 이해했다면, 조건 외의 take 방법을 요청 했습니까? 글쎄, 그 어렵지 않다 :

while (!links.isEmpty()) { 
    try { 
     String link = links.take(); 
     // Do stuff. 
    } catch (InterruptedException e) { 
     // Exception handling. 
    } 
} 

현재 상태 !(link = links.take()).isEmpty() 검사 반환 값이-A가 아닌 큐 (길이가 0 일) 빈 문자열-경우.

어쨌든 위의 코드는 atomic이 아니므로 links.isEmpty()links.take() 사이에 아무 것도 발생하지 않는다고 보장 할 수 없습니다.

편집 :

BlockingQueue<Integer> numbers = new ArrayBlockingQueue<>(10); 
AtomicBoolean flag = new AtomicBoolean(true); 

// Producer. 
new Thread(() -> { 
    for (int i = 0; i < 10; i++) { 
     try { 
      numbers.put(i); 
     } catch (InterruptedException e) { /* NOP */ } 
    } 
    flag.set(false); 
}).start(); 

// Consumer. 
while (flag.get() || !numbers.isEmpty()) { 
    try { 
     System.out.println(numbers.take()); 
    } catch (InterruptedException e) { /* NOP */ } 
} 

AtomicBoolean 여기에 필요하지 않지만 여러 제작자 및/또는 소비자가 있다면 그것은 편리한 될 수 있습니다 당신은 플래그와 함께 시작하는 동안 race conditions를 처리 할 수 ​​있습니다. 또한 체크 아웃해야하는 java.util.concurrent의 일부입니다.

+0

하지만 별도의 질문이지만 생산자 코드 내에서 일정 수의 요소가 소비자에 의해 처리 된 후 생산 중단 시점을 알 수 있습니까? – davidchoo12

+0

이 작업은 비동기 적으로 수행 할 수 있습니다. 'n' 아이템을 소비하길 원한다면,'n'의 용량을 가진'ArrayBlockingQueue'를 생성 할 수 있습니다. 대기열에 충분한 공간이 없으면'put'만이 차단되어 제작자가 발사하고 잊을 수 있습니다. – beatngu13

+0

하지만 소비자가 '테이크'를하면 공간이 생기고 생산자는 대기열에 계속 들어가기 때문에 생산자가 일시 중지되지만 소비자가 여러 항목을 처리하면 완전히 중단됩니다. – davidchoo12

0

내 이해는 좋은 방법으로 BlockingQueue를 종료하는 방법을 묻는 것입니다. 내가 생각할 수있는 두 가지 시나리오가 있습니다. 어떤 경우 든 메시지 생성자 A와 메시지 소비자 B가 있습니다.

  1. 메시지 생성자는 "정지"와 같은 터미널 값 형식을 보냅니다. 당신은 그것을 확인하고 while주기가 끝납니다.
  2. 소비자 측에서 InterruptedException을 throw하는 메시지 생성자를 중단 할 수 있습니다. 터미널 입력을 피하는 방법입니다. 여기서 문제는 소비자가 큐에있는 모든 것을 실제로 사용했다면 제어 할 수 없다는 것입니다. 그래서 인터 럽션은 소비가 즉시 종료되어야하는 조건이있는 경우에 주로 사용됩니다.