Ich habe gerade angefangen Multithreading zu lernen. Ich habe 5 Produzenten und 2 Konsumenten in mehreren Threads. Grundsätzlich fügt dieses Programm 100 Elemente in die Warteschlange ein. Der Producer beendet das Hinzufügen, wenn die Warteschlangengröße 100 beträgt. Ich möchte, dass der Consumer den Producer benachrichtigt, wenn der Consumer alle Elemente aus der Warteschlange entfernt, sodass der Producer das Hinzufügen erneut starten kann. Momentan wartet der Produzent, wird aber vom Verbraucher nie benachrichtigt.Warten und benachrichtigen in Consumer- und Producer-Threads
Hersteller:
public class Producer implements Runnable {
private BlockingQueue sharedQueue;
private final int queueSize;
private Object lock = new Object();
public Producer(BlockingQueue sharedQueue, int queueSize){
this.sharedQueue = sharedQueue;
this.queueSize = queueSize;
}
public void run() {
while(true) {
if(sharedQueue.size()== queueSize){
try {
synchronized (lock) {
sharedQueue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
sharedQueue.put("Producer: " + sharedQueue.size());
Thread.sleep(500);
System.out.println("Producer: Queue Size " + sharedQueue.size() + " Current Thread " + Thread.currentThread());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Verbraucher:
public class Consumer implements Runnable{
private BlockingQueue sharedQueue;
private final int queueSize;
private final int queueEmpty=0;
private Object lock = new Object();
public Consumer(BlockingQueue sharedQueue, int queueSize){
this.sharedQueue = sharedQueue;
this.queueSize = queueSize;
}
//Notify awaiting thread if the sharedQueue is empty
public void run() {
while (true) {
if(sharedQueue.size()==queueEmpty){
synchronized (lock) {
this.notifyAll();
}
}
try {
sharedQueue.take();
Thread.sleep(800);
System.out.println("Consumer: Queue Size " + sharedQueue.size() + " Current Thread" + Thread.currentThread());
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
Hauptklasse
public class App{
//A simple program to illustrate how producer and consumer pattern works with blocking queue using executor service
public static void main(String[] args)
{
final BlockingQueue<String> sharedQueue = new ArrayBlockingQueue<String> (100);
final int queueSize =100;
final int producerNum = 5;
final int consumerNum = 2;
final ExecutorService executorProducer = Executors.newFixedThreadPool(producerNum);
final ExecutorService executorConsumer = Executors.newFixedThreadPool(consumerNum);
for(int i=0;i<producerNum;i++){
Producer producer = new Producer(sharedQueue,queueSize);
executorProducer.execute(producer);
}
for(int j=0;j<consumerNum;j++){
Consumer consumer = new Consumer(sharedQueue,queueSize);
executorConsumer.execute(consumer);
}
}
}
Was denkst du 'this.notifyAll();' tut? Warum denkst du das? –
Dieser Code sollte IllegalMonitorStateException auslösen, wenn notifyAll aufgerufen wird. –
Ich denke, notifyAll wird alle Threads, die auf dieses Objekt warten, aufwachen. Die erwachten Threads können nicht fortfahren, bis der aktuelle Thread die Sperre für dieses Objekt aufgibt. Also mein Fehler hier ist, dass warten und benachrichtigen müssen für das gleiche Objekt verwendet werden? – hao