【问题标题】:Huge CPU impact LinkedBlockingQueue巨大的 CPU 影响 LinkedBlockingQueue
【发布时间】:2012-05-07 15:23:46
【问题描述】:

我有一个名为tasksLinkedBlockingQueue,但是当我调用tasks.take() 并等待任务可用时,CPU 使用率为100%。我有多个线程使用tasks.take() 方法(每个线程都有自己的tasks 变量)。有人知道为什么会这样吗?

tasks 变量的定义

private LinkedBlockingQueue<ComputerTask> tasks;
// snip
this.tasks = new LinkedBlockingQueue<ComputerTask>(100);

执行任务的代码

ComputerTask task = tasks.take();

提供新任务的代码

this.tasks.offer(task);

附:我不知道这是否是我的 Java 版本的问题,因为我还没有在任何其他计算机上测试过。

java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-413-11M3623)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-413, mixed mode)

【问题讨论】:

  • 大概是什么都没有推送任务,队列是空的,是吗?如果是这样,而且肯定是消费者线程在循环,那听起来肯定坏了!
  • 是的。队列是空的,它不像每 0.2 秒左右那样被填满。在它再次被填满之前可能会持续几分钟。那是个问题吗,空虚?然而,它是该程序的关键部分,所以我不能真正把它拿出来。有什么建议吗?
  • @Robbietjuh 我建议您对增加的 CPU 的位置进行更多评估。例如,在没有任何生产者的情况下,让 10 个线程处于等待状态。如果这仍然显示 CPU 增加,那么您在其他地方遇到了问题(为了证明这一点,请编写一个简单的应用程序,在没有其他功能的情况下执行相同的操作)。如果您使用的是标准 JDK,并且只是在 LBQ 上使用takeing,则不会占用 CPU。

标签: java multithreading load cpu


【解决方案1】:

我有一个LinkedBlockingQueue 调用任务,但是当我调用tasks.take() 并等待任务可用时,CPU 使用率为 100%。我有多个线程使用tasks.take() 方法(每个线程都有自己的任务变量)。

tasks.take(); 不应旋转,除非它正在使大量项目出队。如果队列为空,它将阻塞,所以我怀疑这 不是 100% 负载的原因。我会确保您使用分析器或在 take() 周围添加调试语句,以查看它是否被多次调用。

要记住的一点是,如果队列已满,tasks.offer(task) 会立即返回 false。我想知道你应该使用tasks.put(task) 它将阻止而不是旋转。如果您使用offer() 来确定在哪个任务处理程序上运行任务,那么当所有任务处理程序的队列都已满时,您可能正在循环往复?

如果您自己进行任务管理,您可以考虑使用内置的ExecutorService 类之一。然后,您可以提交所有任务或使用阻塞队列,ExecutorService 将处理为池中的每个线程提供其任务:

// start 10 threads handling the tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// now submit tasks to the pools that will be run with the 10 threads
threadPool.submit(task);
...

在上面的例子中ComputerTask必须实现Runnable

【讨论】:

  • 谢谢。我会调查的。我想说的一件事是队列永远不会满,没有足够的任务来做。如果他们这样做了 - 就会出现严重的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多