当前位置: 首页 > 知识库问答 >
问题:

Java BlockingQueue导致线程不必要的等待。

陆光济
2023-03-14

我使用blocking queue(LinkedBlockingQueue)在几个线程之间同步数据。请看下图。

主线程是一个生产者,它产生对象,然后将它们放入每个消费者的队列中(线程2-10)。需要强调的是,每个消费者都有自己的队列,每个产生的对象都将进入所有消费者的队列。

生产者的运行速度比使用者快得多,因此我们可以假设在使用者运行期间队列不应该为空。当任何使用者的队列达到其容量时,生产者将被阻止(生产者使用 put()。消费者使用 take() 从队列中获取对象。

有了这个设置,我会假设当队列为空时,消费者很少(如果可能的话)等待。然而,从我在下面附上的图片中,我可以看到,所有消费者都会不时地排队等待物品;在等待期间,我可以看到制作人正在运行。

这不是我对BlockingQueue的理解,我曾假设,只要生产者生产出某种东西并放入队列,消费者就应该开始工作。我不明白为什么消费者要等这么长时间。

有人可以解释一下吗?有没有简单的方法来分析这种类型的应用程序?

共有1个答案

裴华荣
2023-03-14

这并不是我对BlockingQueue的理解,我认为只要生产者生产出产品并将其放入队列,消费者就应该开始工作。我无法理解为什么消费者线程上有这么长的等待时间。

这很可能不是阻塞队列的问题。

>

  • 你可能不正确,生产者落后于消费者。也许制作人正在崩溃,有一段时间正在从加载的磁盘中读取数据,结果落后了。

    也许消费者正在阻止其他对象而不是 BlockingQueue。消费者如何处理数据?他们是将其写入磁盘还是通过网络发送?他们执行的任何其他操作可以阻止吗?

    另一种可能性是,只有几个线程在跟上生产者的进度,所以有很多线程在以后进先出的线程顺序等待。换句话说,如果一个线程刚刚完成,那么它可能会使用制作者添加的最新元素。因此,有几个线程保持忙碌,而其他线程则处于阻塞状态。我不确定您的队列是否就是这样实现的。

    有什么简单的html" target="_blank">方法来分析这种应用程序吗?

    要做的一件事是查看堆栈跟踪,以查看每个线程被阻塞的位置。如果您的线程实际上正在等待阻塞队列,这将给您一个更好的主意。您可以使用jconsole实时查看线程,或者每隔一段时间发送一个QUIT信号。

  •  类似资料:
    • 我们有一个应用程序,它有一个包含通过数据库填充的成员的类。这里有一个典型的例子。 对于data1、data2、data3…dataN,我们有相同的模式。每个dataStructure都与另一个无关,它们只是在同一个类中。此数据是跨多个线程访问的。关于此模式的几个问题: 同步方法将使线程必须等待跨所有不同的布尔检查,对吗?哪个是不必要的? 数据结构需要同步吗?数据在应用程序的整个生命周期中都不会改变

    • 我正在创建一个实现IAnimal接口的Animal类。然后,Cats和Dogs类都实现了IAnimal接口。目前,我在IAnimal中只保留了3个简单的方法,以便进行简短的演示。主要类动物是通过依赖注入(DI)构建的。 当IAnimal有更多的方法时,例如:Cats类只实现SomethingOnlyCatsDo方法,Dogs类实现SomethingOnlyDogsDo方法,那么每个类内部都会有更多

    • 我很困惑。一个或多个怎么能在单个线程上并行运行?我对并行性的理解显然是错误的。 一些我无法理解的MSDN: 异步和等待关键字不会导致创建额外的线程。异步方法不需要多线程,因为异步方法不会在自己的线程上运行。该方法在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。 .. 以及: 在启动任务和等待任务之间,您可以启动其他任务。其他任务隐式并行运行,但不会创建其他线程。

    • 我有一个,有5列。这些分别是我对列约束的设置。 (固定大小) 整个 基本上是两列形式的布局。我的列 1 和 4(索引 0 和 3)是字段标签,而列 2 和 5 是输入字段(等)。列 3 只是两个表单列之间的固定宽度填充。 我的表单中有一些 - 有些在左列,有些在右列。我已将所有的最大宽度设置为。 加载表单时,布局与我预期的一样(两个输入字段列的宽度相等)。但是,当我单击任何一个<code>组合框<

    • 我正在为一个大型应用程序编写自动化测试。这些测试中的一些很容易成为<code>异步,它只提供<code>async 测试应用程序的一些关键方面如下: 这是一个巨大的ASP.NET应用程序(尽管代码在通过单元测试执行时没有在ASP.NET上下文中运行)。 在其核心中,它严重依赖于每个线程缓存上下文信息(例如活动用户的整个权限方案)的静态对象。 现在,我的问题是当在方法中使用时,延续可能发生在与以前不

    • 问题内容: 我已经使用线程编写了python tkinter代码,以便tkinter向导通过在主线程中运行的tkinter mainloop和在单独线程中运行的后台进程自动更新。但是我注意到,运行代码一段时间后python崩溃了。此外,它本质上是随机的,但python大部分时间都崩溃。我写了一个小的测试代码来显示这个问题(我的原始代码与此类似,但是具有一些实际的过程和许多其他功能,因此我将共享测试