CPU负载中的Java多线程

时间:2013-02-26 14:21:23

标签: java multithreading thread-priority

运行多个Java线程的应用程序存在一些问题。 应用程序运行许多工作线程,这些线程在输入队列中连续查看,如果队列中有消息,则将它们拉出并处理它们。

在这些工作线程中,有另一个验证线程被安排在固定的时间段执行检查以查看主机(应用程序运行的主机)是否仍处于“良好状态”以运行应用程序。此线程更新AtomicBoolean值,而该值又由工作线程验证,然后开始查看主机是否正常。

我的问题是,在CPU负载较高的情况下,负责验证的线程需要更长的时间,因为它必须与所有其他线程竞争。如果AtomicBoolean在一段时间后没有更新,它会自动设置为false,这会给我带来一个令人讨厌的瓶颈。

我最初的方法是提高验证线程的优先级,但深入挖掘它我发现这不是一个保证行为,算法不应该依赖线程优先级来正常运行。

有人有任何其他想法吗?谢谢!

5 个答案:

答案 0 :(得分:1)

使用java.util.concurrent包的LinkedBlockingQueue,而不是窥视常规队列数据结构。

您可以做的是,运行一个线程池(您可以使用执行服务的固定线程池,即您选择的一些工作线程)并执行LinkedBlockingQueue.take()。

如果一条消息到达队列,它将被送到其中一个等待线程(是的,take会阻塞该线程,直到有东西被送入)。

Java API Reference for Linked Blocking Queue's take method

HTH。

答案 1 :(得分:0)

更多线程并不意味着更好的性能。通常,如果你有双核,2个线程提供最佳性能,3个或更多开始变得更糟。四核应该最好处理4个线程,等等。所以要小心你使用多少线程。

你可以让其他线程在执行工作后进入休眠状态,并允许其他线程尽自己的一份力。我相信Thread.yield()会暂停当前线程以给其他线程留出时间。

如果你想让你的线程连续运行,我建议创建两个主线程,线程A和B.使用A作为验证线程,从B中创建其他线程。因此,线程A获得更多的执行时间。

答案 2 :(得分:0)

一种旧的学校限制工作方法,根本没有使用健康检查线程(因此绕过这些问题)是阻止或拒绝如果队列长于所述队列而添加到队列的请求100.这会对生成负载的客户端施加动态反压,在工作线程过载时减慢它们的速度。

此方法已添加到Java 1.5库中,请参阅java.util.concurrent.ArrayBlockingQueue。如果队列已满,则put(o)方法会阻塞。

答案 3 :(得分:0)

您使用的是Executor框架(来自Java的并发包)吗?如果不给它一个机会。您可以尝试使用ScheduledExecutorService作为验证线程。

答案 4 :(得分:0)

似乎你需要利用条件变量。偷看将采取cpu周期。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html