首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多生产者和使用者多线程Java不按预期工作

多生产者和使用者多线程Java不按预期工作
EN

Stack Overflow用户
提问于 2019-09-24 10:49:08
回答 1查看 245关注 0票数 0

我正在研究Java的生产者-消费者问题的多个生产者和消费者用例。代码在github上。同样的实现也适用于单一生产者消费者用例,但对于多个生产者消费者用例却表现得很奇怪。

关于产出,我有几个问题:

一开始,所有生产者和一个消费者都拥有这样的锁:

代码语言:javascript
运行
复制
Producer t1 has lock
t5 produced 1, integerQueue: [1]
Producer t5 notifiedAll
  1. 我认为所有的线程都应该竞争锁,并且最多应该有一个线程拥有所有时间的锁?所有的制作者都共用这个锁吗?当生产者线程t5持有锁时,使用者线程t1是如何获得锁的?

在运行了一段时间之后,出现了另一个奇怪的现象:

代码语言:javascript
运行
复制
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
  1. 似乎除了一个生产者和消费者之外,所有线程都死了,这两个线程在彼此之间切换锁。为什么会发生这种情况?其他生产者和消费者怎么了?

任何帮助都是非常感谢的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-24 12:52:21

您正在使用Producer5运行的单个实例,并多次将其提交给执行服务。

代码语言:javascript
运行
复制
    Producer5 producer = new Producer5(queue, maxCapacity);
    pool.execute(producer);
    pool.execute(producer);
    pool.execute(producer);
    pool.execute(producer);
    pool.execute(producer);

因此,单个Producer5实例中的Producer5字段将被多次覆盖,并且不再有用(它将不再打印实际正在运行的线程的名称,而且它需要是volatile才能被多个线程正确地更新-对于正确的定义)。

代码语言:javascript
运行
复制
  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方法的顶部),最终确定一些值。所有线程现在只打印这个值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58078629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档