저는 Java를 배우며 기본 생산자 - 소비자 용례를 구현하고 있습니다. 대기열과 일부 대기열에 물건을 넣는 생산자가 있습니다. 또한 Callable을 구현하는 Consumer가 하나 있습니다.java while (true) 대기열을 폴링하여 실행하지 않음
public String call() throws Exception
{
while(true) {
if(!queue.isEmpty()) {
String prod = queue.poll();
System.out.println(name + " consumed " + prod);
}
}
}
프로듀서 :
@Override
public void run() {
System.out.println("adding " + name);
queue.add(name);
}
홈페이지 : 여기에 소비자의 구현은
public static void main(String[] args) {
Test();
}
public static void Test()
{
Queue<String> queue = new LinkedList<String>();
ScheduledExecutorService lots_of_producers = Executors.newScheduledThreadPool(10);
ExecutorService consumers = Executors.newFixedThreadPool(1);
for(int i=0; i<1; i++) {
Consumer consumer = new Consumer("consumer_" + i, queue);
consumers.submit(consumer);
}
for(int i=0; i<5; i++) {
Producer producer = new Producer("producer_" + i, queue);
lots_of_producers.scheduleWithFixedDelay(producer, i, 5, TimeUnit.SECONDS);
}
}
생산자가 잘 작동하지만 소비자의 로그를 참조하지 않았기 때문에 소비자가 작동하지 않습니다 .
그러나 소비 구현을 변경하고 queue.isEmpty()가 true 일 때 소비자 스레드가 잠자기 상태가되면 소비자는 예상대로 작동합니다.
public String call() throws Exception
{
while(true) {
if(!queue.isEmpty()) {
String prod = queue.poll();
System.out.println(name + " consumed " + prod);
} else {
Thread.sleep(100);
}
}
}
왜 소비자 스레드가 첫 번째 경우에 작동하지 않는지 설명 할 수 있습니까?
또한 첫 번째 경우에 일식에서 소비자 스레드가 죽지 않았 음을 알 수 있습니다. 일시 중지하고이 줄에서 작업하고 있습니다.
if(!queue.isEmpty()) {
이제 수동으로 단계를 넘기면 소비자가 작업하고 로그를 인쇄합니다. 그러나 내가 다시 시작하고 그것이 스스로 실행되도록하자마자, 다시 붙어있을 것이다.
자바를 더 잘 이해하려고합니다.
감사합니다.
-erben
'BlockingQueue'를 사용해야합니다. –
코드의 다른쪽에 대해서는 아무 것도 표시하지 않았지만 적절한 스레드 안전 큐 구현을 사용하고 있지 않은 것 같습니다. – chrylis
예를 들어 동시 수정 예외로 인해 소비자 작업이 중단 된 경우 집행 담당자가 시끄러운 충돌을 생성하는 대신 결과 나 예외를 반환하는 미래를 반환하기 때문에 예외가 표시되지 않습니다. – zapl