如何在不删除的情况下避免100%的CPU利用率(true)

时间:2013-02-07 23:57:34

标签: java multithreading

我正在研究一个我需要一段时间(真实)的系统,其中循环不断地监听队列并增加内存中的计数。

数据不断进入队列,所以我无法避免一段时间(真实)的情况。但自然它会将我的CPU利用率提高到100%。

那么,我怎样才能保持一个活跃的线程来监听队列尾部并执行一些操作,但同时将CPU利用率降低到100%?

6 个答案:

答案 0 :(得分:10)

完全为此目的发明了{p> Blocking queues

另见:What are the advantages of Blocking Queue in Java?

答案 1 :(得分:2)

LinkedBlockingQueue.take()就是您应该使用的。这等待一个条目到达队列,不需要额外的同步机制。

(Java中有一两个其他阻塞队列,IIRC,但它们的功能使得它们在一般情况下不适合。不知道为什么这么重要的机制被深深埋藏在神秘的类中。)

答案 2 :(得分:2)

通常一个队列有一种从它中检索项目的方法,你的线程将被取消调度(因此使用0%cpu),直到某些东西到达队列......

答案 3 :(得分:2)

根据您对其他答案的评论,您希望拥有一个基于hsqldb更改的队列

一些快速的谷歌搜索出现了:

http://hsqldb.org/doc/guide/triggers-chapt.html

您似乎可以对其进行设置,以便更改导致触发发生,这将通知您编写的实现org.hsqldb.Trigger接口的类。让该类包含对Java中Concurrent包的LinkedBlockingDequeue的引用,并让触发器将更改添加到队列中。

您现在有一个阻塞队列,您的读取线程将阻塞,直到hsqldb触发一个触发器(来自编写器的更新),这会将某些内容放入队列中。然后,等待的线程将解除阻塞并使该项目脱离队列。

答案 4 :(得分:0)

lbalazscs和Brain有很好的答案。我无法分享我的代码,他们很难给我们解决我的问题的确切方法。有一段时间(真实的)不断轮询队列肯定是错误的方式去做。所以,这就是我所做的:

  1. 我使用ScheduledExecutorService延迟10秒。
  2. 我读了一条消息(比如10k)并处理这些消息
  3. 再次调用
  4. 线程并继续“循环”。
  5. 这大大降低了我的CPU使用率。建议欢迎。

答案 5 :(得分:-2)

看书的人回答很多愚蠢的答案,只是浪费时间在学校,而不是我看到的那么多直接逻辑或答案。

while(true)会将您的程序设置为使用Windows算法基本上分配给它的所有CPU功能来运行循环中的内容,通常是尽可能快地反复进行。这并不意味着它在您的应用程序上显示100%,即如果您运行游戏,则空循环.exe将占用您所有的OS CPU能力,游戏仍应按预期运行。它更像是一个视觉错误,类似于Windows空闲过程和其他一些过程。解决方法是添加一个Sleep(1)(至少1毫秒)或更佳的睡眠(5),以确保其他内容可以运行,并确保CPU不会不断地尽可能快地循环while(true)。通常,这会将可视队列中的CPU使用率降低到0%或1%,因为1毫秒对于更老的CPU来说是一个很大的休息时间。

许多while(trues)或通用的无穷循环都是不好的设计,并且可以大大减慢到甚至Sleep(1000)-1秒间隔检查或更高。无限循环并不是总是糟糕的设计,但通常可以改进。.

我很有趣地看到了这个错误,当我像学习12的C弹出窗口并给出所有“愚蠢”的答案时就知道了。

只要知道是否尝试过,除非您学会使用的脚本化较慢的语言本身已将其修复,否则Windows会声称在OS实际具有空循环时会占用大量CPU。免费的资源来花费。