2012-05-07 31 views
0

我有一个LinkedBlockingQueue调用tasks,但是当我呼叫tasks.take()并等待任务变为可用时,CPU使用率为100%。我有多个使用tasks.take()方法的线程(每个线程都有自己的tasks变量)。有人知道为什么会发生这种情况吗?巨大的CPU影响LinkedBlockingQueue

Defenition的tasks变量

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

守则采取了任务

ComputerTask task = tasks.take(); 

代码提供了一个新的任务

this.tasks.offer(task); 

P.S.我不知道这是否与我的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

假设没有任何东西在推动任务,队列是空的,是吗?如果是这样,并且肯定是正在循环的消费者线程,那肯定听起来不合适! –

+0

是的。队列是空的,它不是像每0.2秒左右填满一样。可能会持续几分钟才能再次充满。那么这是一个问题,空虚吗?然而,这是该计划的关键部分,所以我不能把它拿出来。任何建议? – Robbietjuh

+0

@Robbietjuh我建议你对增加CPU的位置做一些更多的评估。例如,有10个线程只是坐在没有任何生产者。如果这仍然显示CPU增加,那么在其他地方有问题(为了证明这写了一个简单的应用程序,没有其他功能相同的事情)。如果您使用的是标准JDK,并且只是在LBQ上运行,则不会有CPU使用率。 –

回答

2

我打算把我的意见变成一个答案。

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

+0

谢谢。我会研究它。有一件事我想说的是队列永远不会满员,没有足够的任务来完成。如果他们这样做 - 有严重的错误。 – Robbietjuh

相关问题