나는 ArrayBlockingQueue가 구현 된 BlockingQueue 인터페이스를 연구 중이었습니다.ArrayBlockingQueue weired behavior를 보여줍니다.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class MainJava {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
new Thread(producer).start();
new Thread(consumer).start();
}
}
class Producer implements Runnable {
BlockingQueue<String> queue = null;
public Producer(BlockingQueue<String> queue) {
this.queue = queue;
// TODO Auto-generated constructor stub
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("Producer added " + i);
queue.put(String.valueOf(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
BlockingQueue<String> queue = null;
public Consumer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("Consumer used " + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
예상되는 동작
Producer add 0
Consumer used 0
Producer add 1
Consumer used 1
and so on..
Actaul O/P
Producer added 0
Producer added 1
Consumer used 0
Consumer used 1
Producer added 2
Producer added 3
Producer added 4
나는 그것이 제대로 작동 디버그 모드를 사용하여 시도 : 데모 목적을 위해 내가 개발할 다음 코드가 . 그렇다면 왜 디버그 모드가 없으면 제대로 작동하지 않는 것입니까? 당신의 생산에서
: 그것은 당신의 대기열이 불운 타이밍에 의한 한 번에 두 개 이상의 항목을 포함 할 것 같은 '환상'과 잘못된 장소에서 System.out.println
입니다 -
두 스레드가 서로 병렬로 실행 중이기 때문에 이러한 현상이 발생합니다! 그들의 행동을 예측할 수는 없습니다! – ItachiUchiha
@ItachiUchiha 실제로 그는 크기 1의 블로킹 큐를 가지고있어서 항상 대기하고 있습니다. 여기서 "문제"는 System.out.println의 출력을 신뢰하여 올바르게 작동하는지 여부를 결정하는데, 신뢰할 수는 없습니다. – Kayaman
내 두 스레드는 하나의 항목을 추가하는 다른 항목을 추가하는 que를 사용합니다. 생산자가 하나의 항목을 추가하고 차단해야하는 다른 항목을 추가하려고하면 que가 비어있을 때까지 항목이 대기열에 추가 될 때까지 차단해야합니다. BlockingQueue를 올바르게 사용할 수 있습니까? – user3608352