【发布时间】:2019-05-24 06:01:45
【问题描述】:
我已经实现了生产者和消费者的经典示例。这里生产者将在生产 value = 0 后休眠 10 秒 [不会等待状态,因为队列大小小于 10 ]。消费者将消费value =0 并通知生产者将休眠一秒。
所以我的问题是,为什么消费者的通知没有中断生产者线程并打印Producer Exception cached。
下面程序的输出是这样的:
Producer add value=0
Consumer consumes value=0
(等待 10 秒)
Producer add value=1
Consumer consumes value=1
(等待 10 秒)
Producer add value=2
Consumer consumes value=2
生产者和消费者的经典例子。
public class ClassicalProducerConsumer{
public static void main(String[] args) {
Buffer buffer = new Buffer(3);
Thread producer = new Thread(new Runnable() {
@Override
public void run() {
try {
int value = 0;
while (true) {
buffer.add(value);
value++;
Thread.sleep(10000); // Make producer wait for 10 seconds.
}
}catch (Exception ex){
System.out.println("Producer Exception cached");
ex.printStackTrace();
}
}
});
Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
int value = buffer.poll();
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Consumer Exception cached");
e.printStackTrace();
}
}
});
producer.start();
consumer.start();
}
}
class Buffer{
Queue<Integer> queue;
int size;
public Buffer(int size) {
this.size = size;
queue = new LinkedList<>();
}
public void add(int value) throws InterruptedException {
synchronized (this){
while (queue.size() >=size){
wait();
}
System.out.println("Producer add value="+ value);
queue.add(value);
notify();
}
}
public int poll() throws InterruptedException {
synchronized (this){
while (queue.size()==0){
wait();
}
int value = queue.poll();
System.out.println("Consumer consumes value="+ value);
notify();
return value;
}
}
}
【问题讨论】:
-
notify和interrupt是两种不同的机制。 -
因为可能有多个线程在等待这样的生产者/消费者问题,所以我通常更喜欢使用
notifyAll(),以确保任何可能的线程不会被饿死或错过。
标签: java multithreading producer-consumer java.util.concurrent