我尝试使用wait()
和notifyAll()
方法实施生产者消费者模式,但存在一些问题。所以我的代码就是下一个。
主要课程:
import java.util.LinkedList;
import java.util.List;
public class TestThread {
public static void main(String[] args) {
final List testQueue = new LinkedList();
final Producer producer = new Producer(testQueue);
final Consumer consumer = new Consumer(testQueue);
Runnable prodThread = new Runnable() {
@Override
public void run() {
producer.putMessages();
}
};
Runnable consThread = new Runnable() {
@Override
public void run() {
consumer.readMessages();
}
};
(new Thread(prodThread)).start();
(new Thread(consThread)).start();
}
}
制作课程:
class Producer {
private final List queue;
public Producer(List queue) {
this.queue = queue;
}
public void putMessages() {
// Add batch of messages to queue
for (int t = 1; t <= 2; t++) {
synchronized (queue) {
try {
// if size of queue is more then 2, then wait
while (queue.size() > 1) {
System.out.println("Producer: Queue is full! Size of queue is " + queue.size() +", so Producer is waiting...");
queue.wait();
// Consumer could start own work here
}
for (int i = 0; i < 2; i ++) {
queue.add("String" + (i+1)*t);
System.out.println("Producer: Message -" + queue.get(i) + "- was added to queue...");
}
System.out.println("Producer added batch of messages, let's notify our Consumer...");
queue.notifyAll(); // consumer thread should be in wait set
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
}
消费者类:
class Consumer {
private final List queue;
public Consumer(List queue) {
this.queue = queue;
}
public void readMessages() {
synchronized (queue) {
try {
//while queue is empty let's wait - producer will get processor time in this case
while (queue.isEmpty()) {
System.out.println("Consumer: Queue is empty! Nothing to read, so Consumer is waiting...");
queue.wait();
}
for (int k = 0; k < queue.size(); k++) {
System.out.println("Consumer: Read messages from queue -" + queue.get(k) + " -");
}
//clean our queue
queue.removeAll(queue);
if (queue.isEmpty()) {
System.out.println("Consumer finished reading, notify Producer that queue is empty, please start adding new messages for me!");
queue.notifyAll();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
程序执行的结果:
Consumer: Queue is empty! Nothing to read, so Consumer is waiting...
Producer: Message -String1- was added to queue...
Producer: Message -String2- was added to queue...
Producer added batch of messages, let's notify our Consumer...
Consumer: Read messages from queue -String1 -
Consumer: Read messages from queue -String2 -
Consumer finished reading, notify Producer that queue is empty, please start adding new messages for me!
Producer: Message -String2- was added to queue...
Producer: Message -String4- was added to queue...
Producer added batch of messages, let's notify our Consumer...
根据我的代码,我希望消费者读取来自制作人(String2
,String4
的最后消息并打印结果。但是没有发生,我的代码出了什么问题?
答案 0 :(得分:1)
您运行消费者的主题按预期进入readMessages()
。这里没有循环机制,因此在消耗前两条消息之后它继续执行并退出方法。
您的制作人通知所有感兴趣的线程队列中有消息,但消费者没有收听。消费者存在的线程已经终止。