多个生产者和消费者多线程 Java 未按预期工作
Multiple Producer and Consumer Multithreading Java Not Working as Intended
我正在研究 Java 的生产者-消费者问题的多个生产者和消费者用例。该代码在 github. The same implementation worked for the single producer consumer 用例中,但在多生产者消费者用例中表现得很奇怪。
我对输出有一些疑问:
一开始,所有生产者和一个消费者都有锁:
Producer t1 has lock
t5 produced 1, integerQueue: [1]
Producer t5 notifiedAll
- 我认为所有线程都应该竞争锁,并且最多应该有一个线程拥有所有时间的锁?所有生产者都共享锁吗?生产者线程 t1 持有时,消费者线程 t5 是如何获得锁的?
运行一段时间后,又出现了一个奇怪的现象:
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
- 似乎除了一个生产者和消费者之外的所有线程都已死亡,而这两个线程正在相互切换锁。为什么会这样?所有其他生产者和消费者怎么了?
非常感谢任何帮助。
您正在使用 Producer5
runnable 的单个实例并将其多次提交给执行服务。
Producer5 producer = new Producer5(queue, maxCapacity);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
所以你在那个单一 Producer5
实例中的 threadName
字段将被覆盖多次并且没有用(它将不再打印出实际上是 [=33= 的线程的名称) ],此外,它需要 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
实例。为每个执行线程创建一个单独的实例。
How did consumer thread t5 get the lock while producer thread t1 was holding it?
它仍然是线程 t1 运行 此代码,但 threadName
字段同时已被线程 t5 更新。高度误导的输出。
It seems all threads except one producer and consumer had died and those 2 are switching lock between each other.
线程都还活着,但是只有两个threadName
字段存在,线程一直在轮流更新(在run
方法的顶部),最后确定一些价值。所有线程现在只打印该值。
我正在研究 Java 的生产者-消费者问题的多个生产者和消费者用例。该代码在 github. The same implementation worked for the single producer consumer 用例中,但在多生产者消费者用例中表现得很奇怪。
我对输出有一些疑问:
一开始,所有生产者和一个消费者都有锁:
Producer t1 has lock
t5 produced 1, integerQueue: [1]
Producer t5 notifiedAll
- 我认为所有线程都应该竞争锁,并且最多应该有一个线程拥有所有时间的锁?所有生产者都共享锁吗?生产者线程 t1 持有时,消费者线程 t5 是如何获得锁的?
运行一段时间后,又出现了一个奇怪的现象:
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
- 似乎除了一个生产者和消费者之外的所有线程都已死亡,而这两个线程正在相互切换锁。为什么会这样?所有其他生产者和消费者怎么了?
非常感谢任何帮助。
您正在使用 Producer5
runnable 的单个实例并将其多次提交给执行服务。
Producer5 producer = new Producer5(queue, maxCapacity);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
pool.execute(producer);
所以你在那个单一 Producer5
实例中的 threadName
字段将被覆盖多次并且没有用(它将不再打印出实际上是 [=33= 的线程的名称) ],此外,它需要 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
实例。为每个执行线程创建一个单独的实例。
How did consumer thread t5 get the lock while producer thread t1 was holding it?
它仍然是线程 t1 运行 此代码,但 threadName
字段同时已被线程 t5 更新。高度误导的输出。
It seems all threads except one producer and consumer had died and those 2 are switching lock between each other.
线程都还活着,但是只有两个threadName
字段存在,线程一直在轮流更新(在run
方法的顶部),最后确定一些价值。所有线程现在只打印该值。