Я написал программу производителя / потребителя, как показано ниже.
package com.myjava.concurrency.basics.waitnotify;
import java.util.PriorityQueue;
import java.util.Queue;
public class SharedObject {
private Queue<String> dataObject;
private final Object objLock = new Object();
public SharedObject() {
dataObject = new PriorityQueue<String>(1);
}
public void writeData(String data) {
synchronized (objLock) {
while (!dataObject.isEmpty()) {
System.out.println("Producer:Waiting");
try {
objLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
dataObject.offer(data);
System.out.println(String.format("%s : %s",
Thread.currentThread().getName(), data));
objLock.notify();
}
}
public String readData() {
String result = null;
synchronized (objLock) {
while (dataObject.isEmpty()) {
System.out.println("Consumer:Waiting");
try {
objLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
result = dataObject.poll();
System.out.println(String.format("%s : %s",
Thread.currentThread().getName(), result));
objLock.notify();
}
return result;
}
}
package com.myjava.concurrency.basics.waitnotify;
import java.util.Arrays;
import java.util.List;
public class TestWaitNotify {
public static void main(String[] args) {
SharedObject sharedObject = new SharedObject();
List<String> fruitsList = Arrays.asList("Apple", "Banana", "Orange");
int listSize = fruitsList.size();
Thread producer = new Thread(() -> {
System.out.println("producer thread started");
fruitsList.forEach(p -> {
sharedObject.writeData(p);
});
}, "producer");
Thread consumer = new Thread(() -> {
System.out.println("consumer thread started");
for (int i = 0; i < listSize; i++) {
sharedObject.readData();
}
}, "consumer");
consumer.start();
producer.start();
}
}
Я получил вывод, как показано ниже:
producer thread started
consumer thread started
Consumer:Waiting
producer : Apple
Producer:Waiting
consumer : Apple
Consumer:Waiting
producer : Banana
Producer:Waiting
consumer : Banana
Consumer:Waiting
producer : Orange
consumer : Orange
Вот мой вопрос:
Я ожидал следующую последовательность с этой программой:
producer thread started
consumer thread started
Consumer:Waiting // assuming consumer thread begins first
producer : Apple
consumer : Apple
producer : Banana
consumer : Banana
producer : Orange
consumer : Orange
Только потребительский поток должен входить в режим ожидания только один раз. После первого уведомления потоки не должны входить в цикл while, потому что, когда поток производителя имеет блокировку объекта, потребитель должен ждать блокировки, а когда потребитель снимает блокировку, производитель должен получить блокировку.
Любая помощь приветствуется.