gpt4 book ai didi

java - Java中生产者-消费者代码的多线程没有给出正确的输出?

转载 作者:行者123 更新时间:2023-12-01 06:32:39 24 4
gpt4 key购买 nike

我正在使用多线程解决经典的生产者-消费者问题。我正在使用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();

最佳答案

But both are supposed to happen concurrently?

这里的问题是生产(和消费)只需要很少的时间。你看到的就是所谓的(非关键)race condition生产者甚至可以在消费者开始之前生产所有 10 种商品。通过竞争条件,我的意思是你的两个线程正在相互竞争以生产和消费,在这种情况下不是错误。

如果您将测试增加到(比方说)100000 个项目,您会看到生产和消费消息混合在一起,尽管即使如此,您也可能会看到生产消费 消息 block 长度为 10 或更长。

要尝试的另一件事是首先启动消费者,然后在启动它后放置一个 Thread.sleep(10); ,以便它等待生产者。然后,消费者将有时间调用 wait(),并且一旦第一个 notifyAll 就会从 WAIT 转移到 BLOCKED () 被调用。但即便如此,竞争条件也可能会在消费之前显示所有生产消息。这就是多线程应用程序的异步本质。

附:正确处理 InterruptedException 始终是一个很好的模式。你应该这样做:

try {
wait(); // give up lock and wait
} catch (InterruptedException e) {
// reset the thread interrupt flag
Thread.currentThread().interrupt();
// probably stopping the thread is best
return;
}

关于java - Java中生产者-消费者代码的多线程没有给出正确的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18521674/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com