Java-Parallelität: Multi-Producer-One-Consumer
Ich habe eine Situation, in der verschiedene Threads eine Warteschlange (Produzenten) füllen und ein Verbraucher Element aus dieser Warteschlange abrufen. Mein Problem ist, dass, wenn eines dieser Elemente aus der Warteschlange abgerufen wird, einige fehlen (fehlendes Signal?). Der Herstellercode lautet:
<code>class Producer implements Runnable { private Consumer consumer; Producer(Consumer consumer) { this.consumer = consumer; } @Override public void run() { consumer.send("message"); } } </code>
und sie werden erstellt und ausgeführt mit:
<code>ExecutorService executor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 20; i++) { executor.execute(new Producer(consumer)); } </code>
Der Verbrauchercode lautet:
<code>class Consumer implements Runnable { private Queue<String> queue = new ConcurrentLinkedQueue<String>(); void send(String message) { synchronized (queue) { queue.add(message); System.out.println("SIZE: " + queue.size()); queue.notify(); } } @Override public void run() { int counter = 0; synchronized (queue) { while(true) { try { System.out.println("SLEEP"); queue.wait(10); } catch (InterruptedException e) { Thread.interrupted(); } System.out.println(counter); if (!queue.isEmpty()) { queue.poll(); counter++; } } } } } </code>
Wenn der Code ausgeführt wird, werden manchmal 20 Elemente hinzugefügt und 20 abgerufen. In anderen Fällen werden jedoch weniger als 20 Elemente abgerufen.