我正在开发一个需要一段时间(true)的系统,其中循环不断侦听队列并增加内存中的计数。
数据不断地进入队列,所以我无法避免 while(true) 条件。但自然它会将我的 CPU 利用率提高到 100%。
那么,我怎样才能让一个线程保持活动状态,它监听队列尾部并执行一些操作,但同时将 CPU 利用率降低到 100%?
我正在开发一个需要一段时间(true)的系统,其中循环不断侦听队列并增加内存中的计数。
数据不断地进入队列,所以我无法避免 while(true) 条件。但自然它会将我的 CPU 利用率提高到 100%。
那么,我怎样才能让一个线程保持活动状态,它监听队列尾部并执行一些操作,但同时将 CPU 利用率降低到 100%?
阻塞队列正是为此目的而发明的。
另请参阅:Java 中阻塞队列的优点是什么?
根据您对另一个答案的评论,您希望有一个基于 hsqldb 更改的队列
一些快速的谷歌搜索出现了:
http://hsqldb.org/doc/guide/triggers-chapt.html
看来您可以对其进行设置,以便更改导致发生触发器,该触发器将通知您编写的实现org.hsqldb.Trigger
接口的类。让该类包含对LinkedBlockingDequeue
Java 中 Concurrent 包中的 a 的引用,并让触发器将更改添加到队列中。
您现在有一个阻塞队列,您的读取线程将阻塞该队列,直到 hsqldb 触发触发器(来自写入器的更新),该触发器会将某些内容放入队列中。然后等待的线程将解除阻塞并将项目从队列中移出。
LinkedBlockingQueue.take() 是您应该使用的。这等待条目到达队列,不需要额外的同步机制。
(Java,IIRC 中还有一两个其他阻塞队列,但它们的特性使其不适用于一般情况。不知道为什么如此重要的机制在神秘的类中被埋得如此之深。)
通常,队列有办法从中检索项目,并且您的线程将被取消调度(因此使用 0% cpu),直到有东西到达队列...
lbalazscs 和 Brain 有很好的答案。我无法分享我的代码,他们很难为我的问题提供确切的解决方案。并且有一段时间(true)不断地轮询队列肯定是错误的方法。所以,这就是我所做的:
ScheduledExecutorService
了 10 秒的延迟。 这大大减少了我的 CPU 使用率。欢迎提出建议。
阅读书籍并且只在学校浪费时间的人提供了很多愚蠢的答案,而不是我看到的直接逻辑或答案。
while(true) 将设置您的程序以使用基本上由 Windows 算法“分配”给它的所有 CPU 能力来运行循环中的内容,通常一遍又一遍地尽可能快地运行。这并不意味着如果它在您的应用程序上显示 100%,如果您运行游戏,您的空循环 .exe 将占用您所有的操作系统 CPU 资源,游戏仍应按预期运行。它更像是一个视觉错误,类似于windows空闲进程和其他一些进程。解决方法是添加 Sleep(1)(至少 1 毫秒)或更好的 Sleep(5),以确保其他东西可以运行并确保 CPU 不会尽可能快地不断循环您的 while(true)。这通常会将视觉队列中的 CPU 使用率降至 0% 或 1%,因为 1 毫秒对于更老的 CPU 来说是一个很大的休息时间。
很多时候,while(trues) 或通用的无限循环是糟糕的设计,并且可以大大减慢到甚至 Sleep(1000) - 1 秒间隔检查或更高。无限循环并不总是糟糕的设计,但通常可以改进它们。
有趣的是,当我像 12 岁时学习 C 弹出并给出所有“愚蠢”的答案时,我学到了这个错误。
只要知道您是否尝试过,除非您学会使用的脚本化较慢的语言本身已将其固定在某个位置,否则当操作系统实际上有空闲资源时,Windows 会声称在执行空循环时会使用大量 CPU花费。