我正在研究Java的生产者-消费者问题的多个生产者和消费者用例。代码在github上。同样的实现也适用于单一生产者消费者用例,但对于多个生产者消费者用例却表现得很奇怪。
关于产出,我有几个问题:
一开始,所有生产者和一个消费者都拥有这样的锁:
Producer t1 has lock
t5 produced 1, integerQueue: [1]
Producer t5 notifiedAll
在运行了一段时间之后,出现了另一个奇怪的现象:
Producer t5 has lock
t5 produced 10, integerQueue: [8, 9, 10]
Producer t5 notifiedAll
Producer t5 has lock
t5 produced 11, integerQueue: [8, 9, 10, 11]
Producer t5 notifiedAll
Consumer t8 has lock
t8 consumed 8, integerQueue: [9, 10, 11]
Consumer t8 notified All
Consumer t8 has lock
t8 consumed 9, integerQueue: [10, 11]
Consumer t8 notified All
任何帮助都是非常感谢的。
发布于 2019-09-24 12:52:21
您正在使用Producer5
运行的单个实例,并多次将其提交给执行服务。
Producer5 producer = new Producer5(queue, maxCapacity);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
因此,单个Producer5
实例中的Producer5
字段将被多次覆盖,并且不再有用(它将不再打印实际正在运行的线程的名称,而且它需要是volatile
才能被多个线程正确地更新-对于正确的定义)。
System.out.println(String.format("\nProducer %s has lock",
threadName // this will be the name of the last thread that entered `run`,
// they all share the same instance
));
如果同一个Runnable
实例包含可变状态,则不要重用它.为每个执行线程创建一个单独的实例。
当生产者线程t5持有锁时,使用者线程t1是如何获得锁的?
运行此代码的仍然是线程t1,但threadName
字段在平均时间内已由线程t5更新。极具误导性的输出
似乎除了一个生产者和消费者之外,所有线程都死了,这两个线程在彼此之间切换锁。
线程都还活着,但是只有两个threadName
字段存在,线程轮流更新(在run
方法的顶部),最终确定一些值。所有线程现在只打印这个值。
https://stackoverflow.com/questions/58078629
复制相似问题