我正在使用多线程解决经典的生产者-消费者问题。我在代码中使用wait()
和notifyAll()
。我的问题是当notifyAll
通知其他等待线程恢复时,它不会立即恢复。这是为什么?代码如下
public class ConsumerProducer {
private int count;
public synchronized void consume() {
while (count == 0) { // keep waiting if nothing is produced to consume
try {
wait(); // give up lock and wait
} catch (InterruptedException e) {
// keep trying
}
}
count--; // consume
System.out.println(Thread.currentThread().getName() + " after consuming " + count);
}
public synchronized void produce() {
count++; //produce
System.out.println(Thread.currentThread().getName() + " after producing " + count);
notifyAll(); // notify waiting threads to resume
}
}
客户端代码:
public class ConsumerProducerTest implements Runnable {
boolean isConsumer;
ConsumerProducer cp;
public ConsumerProducerTest(boolean isConsumer, ConsumerProducer cp) {
this.isConsumer = isConsumer;
this.cp = cp;
}
public static void main(String[] args) {
ConsumerProducer cp = new ConsumerProducer(); //shared by both threads to communicate
Thread producer = new Thread(new ConsumerProducerTest(false, cp));
Thread consumer = new Thread(new ConsumerProducerTest(true, cp));
producer.start();
consumer.start();
//producer.start();
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
if (!isConsumer) {
cp.produce();
} else {
cp.consume();
}
}
输出是:
Thread-1 after producing 1
Thread-1 after producing 2
Thread-1 after producing 3
Thread-1 after producing 4
Thread-1 after producing 5
Thread-1 after producing 6
Thread-1 after producing 7
Thread-1 after producing 8
Thread-1 after producing 9
Thread-1 after producing 10
Thread-2 after consuming 9
Thread-2 after consuming 8
Thread-2 after consuming 7
Thread-2 after consuming 6
Thread-2 after consuming 5
Thread-2 after consuming 4
Thread-2 after consuming 3
Thread-2 after consuming 2
Thread-2 after consuming 1
Thread-2 after consuming 0
打印完上面的第一行之后,调用 notifyAll 并且等待线程应该恢复,打印Thread-2 after consuming 0
。我看到的问题Thread-1 (Thread-1 after producing)
是完成后,恢复 Thread-2。但两者都应该同时发生吗?请帮帮我。谢谢 编辑:在 main 方法中有 join() ,并没有改变输出:
producer.start();
producer.join();
consumer.start();