生产者消费者上的Java多线程

生产者消费者上的Java多线程,java,multithreading,algorithm,Java,Multithreading,Algorithm,我正在学习一个关于Java多线程的视频教程。它介绍了如何使用Java实现著名的“生产者-消费者”问题 它使用wait()和notifyAll()来确保生产者线程和使用者线程之间的正确通信 导师故意创建了几个生产者线程,而只有一个消费者线程,但他没有回答一个问题:“生产者线程和消费者线程的数量相等始终是最佳做法,如果生产者线程多于消费者线程,则会出现问题” 然而,他没有具体说明问题是什么。我个人认为那只会是一个篮子满了的情况。专家们能帮忙吗?谢谢。除了生产者效率问题,我看不出还有什么问题。如果生产

我正在学习一个关于Java多线程的视频教程。它介绍了如何使用Java实现著名的“生产者-消费者”问题

它使用wait()和notifyAll()来确保生产者线程和使用者线程之间的正确通信

导师故意创建了几个生产者线程,而只有一个消费者线程,但他没有回答一个问题:“生产者线程和消费者线程的数量相等始终是最佳做法,如果生产者线程多于消费者线程,则会出现问题”


然而,他没有具体说明问题是什么。我个人认为那只会是一个篮子满了的情况。专家们能帮忙吗?谢谢。

除了生产者效率问题,我看不出还有什么问题。如果生产者比消费者多,并且他们都以相同的速度生产/消费,那么多余的生产者将实际上处于闲置状态


例如,请参见此处,建议您将
n+1
作业分配给
n
核心,以便它们始终处于满载状态。

您可以拥有任意数量的生产者和消费者

如果生产者的生产速度过快,队列将被填满,直到出现内存问题,或者生产者被迫保持空闲,直到队列中还有剩余的位置


如果消费者消费过快,他们大部分时间都会处于闲置状态

好吧,问题在于资源的最佳使用,即CPU和内存。正如您正确猜测的那样,篮子将满(因此消耗更多内存),生产者线程将空闲一段时间,直到消费者清空篮子以执行新任务,这将导致CPU利用率不足

如果生产者和消费者的数量相等,则线程组(生产者和消费者)都将忙于执行任务,而篮子也将有稳定的存储空间


现在,太大或太少的生产者/消费者也将是一个问题。大量踏板将占用CPU,从而导致其他问题(减速等)。因此,始终存在一个取决于机器上可用硬件资源的最佳数量。

@JB Nizet很好地总结了这种情况,因为您可能有太多的生产者或太多的消费者。决定因素仅仅是生产者的生产速度与消费者的消费速度之比。换句话说,如果生产一种资源比消耗它花费的时间要长得多,那么最好是生产者多于消费者。然而,如果消耗资源比生产资源需要更多的时间,那么最好是消费者多于生产者


导师可能会假设消费过程比生产过程更有效,这在许多情况下甚至可能在大多数情况下都是正确的,但这不一定是一个好的假设。在设计生产者/消费者系统时,请记住这一点。

我认为这不取决于消费者/生产者的数量,而首先取决于速度。您可能有1个消费者可以在10毫秒内处理1条消息,2个生产者可以在100毫秒内分别生成1条消息

生产商和供应商数量相等始终是最佳做法 消费线程

我个人不同意这一点

有多少生产者和消费者线程完全取决于情况。 对此没有直接的规则

我会告诉你我的情况

我们有一个程序,它读取CSV文件,从中创建XML,并在JMS队列中发布这些XML。这个程序一开始是单线程的,但是性能没有达到标准。我们发现将消息发布到队列需要花费很多时间。所以我们决定引入多线程

我们把逻辑分成两条线-

  • 制作人

    读取CSV并创建XML

  • 消费者

    将XML发送到JMS队列

  • 我们决定只有一个生产者,因为我们不想为文件打开多个句柄,尽管这是可能的。 另一方面,我们保持要创建的消费线程的数量是可配置的,它工作得很好,我们获得了预期的性能增益

    总而言之,您需要确保生产者线程和消费者线程的速度几乎匹配。否则,如果消费者线程比生产者线程慢,记录将堆积在内存(RAM)中,这可能导致Extream情况下的OutOfMemory。