【问题标题】:Multiple Producer and Consumer Multithreading Java Not Working as Intended多生产者和消费者多线程 Java 未按预期工作
【发布时间】:2020-01-24 11:30:16
【问题描述】:

我正在研究 Java 的生产者-消费者问题的多生产者和消费者用例。代码在github。相同的实现适用于 single producer consumer 用例,但在多生产者消费者情况下表现异常。

我对输出有一些疑问:

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

Producer t1 has lock
t5 produced 1, integerQueue: [1]
Producer t5 notifiedAll
  1. 我认为所有线程都应该争夺锁,并且最多应该有一个线程拥有所有时间的锁?所有生产者都共享锁吗?生产者线程 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
  1. 似乎除了一个生产者和消费者之外的所有线程都已死亡,而这两个线程正在相互切换锁。为什么会这样?所有其他生产者和消费者发生了什么?

非常感谢任何帮助。

【问题讨论】:

  • 是的,我的错。

标签: java multithreading locking producer-consumer


【解决方案1】:

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

    Producer5 producer = new Producer5(queue, maxCapacity);
    pool.execute(producer);
    pool.execute(producer);
    pool.execute(producer);
    pool.execute(producer);
    pool.execute(producer);

因此,您在该单个 Producer5 实例中的 threadName 字段将被覆盖多次并且没有用(它将不再打印出实际运行的线程的名称,而且它需要是 @987654325 @ 以便被多个线程正确更新——对于正确的一些定义。

  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 实例包含可变状态,则不要重复使用它。为每个执行线程创建一个单独的实例。


生产者线程 t1 持有锁时,消费者线程 t5 是如何获得锁的?

它仍然是线程 t1 运行此代码,但 threadName 字段同时已由线程 t5 更新。高度误导的输出。

似乎除了一个生产者和消费者之外的所有线程都已死亡,而这两个线程正在相互切换锁。

线程都还活着,但只有两个threadName 字段存在,线程一直在轮流更新(在run 方法的顶部),最终确定了一些值。现在所有线程都打印该值。

【讨论】:

    猜你喜欢
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多