CPU负载中的Java多线程

CPU负载中的Java多线程,java,multithreading,thread-priority,Java,Multithreading,Thread Priority,对于运行多个Java线程的应用程序,我有一点问题。 应用程序运行多个工作线程,这些线程不断地查看输入队列,如果队列中有消息,它们会将消息拉出并处理它们 在这些工作线程中,还有另一个验证线程计划在固定的时间段执行一项检查,以查看主机(应用程序在其上运行)是否仍处于运行应用程序的“良好状态”。此线程更新一个AtomicBoolean值,工作线程在开始查看主机是否正常之前会验证该值 我的问题是,在CPU负载较高的情况下,负责验证的线程将花费更长的时间,因为它必须与所有其他线程竞争。如果AtomicBo

对于运行多个Java线程的应用程序,我有一点问题。 应用程序运行多个工作线程,这些线程不断地查看输入队列,如果队列中有消息,它们会将消息拉出并处理它们

在这些工作线程中,还有另一个验证线程计划在固定的时间段执行一项检查,以查看主机(应用程序在其上运行)是否仍处于运行应用程序的“良好状态”。此线程更新一个
AtomicBoolean
值,工作线程在开始查看主机是否正常之前会验证该值

我的问题是,在CPU负载较高的情况下,负责验证的线程将花费更长的时间,因为它必须与所有其他线程竞争。如果
AtomicBoolean
在一段时间后没有得到更新,它会自动设置为false,这会造成严重的瓶颈

我最初的方法是增加验证线程的优先级,但深入研究后,我发现这不是一种有保证的行为,算法不应该依赖线程优先级来正确运行


有人有别的想法吗?谢谢

更多线程并不意味着性能更好。通常,如果您有双核,2个线程的性能最好,3个或更多线程的性能开始变差。四核处理器最好处理4个线程,等等。所以要小心使用多少线程

您可以在其他线程执行其工作后将其置于睡眠状态,并允许其他线程完成其部分工作。我相信Thread.yield()会暂停当前线程以给其他线程留出时间


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

一种老式的控制工作速率的方法,根本不使用运行状况检查线程(因此绕过这些问题),如果队列长度超过100,则阻止或拒绝添加到队列中的请求。这会对生成负载的客户端施加动态背压,从而在工作线程负载过大时减慢它们的速度


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

您是否正在使用Executor框架(来自Java的并发包)?如果没有,那就试试看。您可以尝试为验证线程使用ScheduledExecutorService。

似乎需要使用条件变量。窥视将占用cpu周期


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

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

如果消息到达队列,它将被馈送到一个等待的线程(是的,take会阻止线程,直到有东西要馈送)


HTH.

通常情况下,优先级不应影响正常功能,但这似乎是一个调整问题。假设验证线程的CPU负载较低,并且工作人员需要更多的CPU,则降低优先级。也,请确保原子的超时值没有设置得太低。再次:向我们显示
验证线程的源代码。
。不幸的是,我无法触摸队列,因为它们在限制范围内。我认为默认情况下,线程的优先级是创建它的线程的优先级,因此在您描述线程的情况下使用线程B创建的线程将具有与线程A相同的优先级。如果我错了,请纠正我可能是,我不确定,但我在这里要说的是,您一直在线程A和B之间切换。B将需要运行多个线程,而A将是单个线程,因此A将获得更多的时间。所谓优先级,我并不是指线程的优先级,我的意思是它将有更多的执行时间。让我更正一下,让它更清楚。我实际上使用ScheduledThreadPoolExecutor作为验证线程。其他线程也使用ScheduledThreadPoolExecutor创建,但位于不同的池中。这些线程执行的作业有一个while循环,因此它们会连续执行。也许我遗漏了什么。附议。不要只是旋转和窥视工作线程,让它们在无事可做时等待队列上的锁或块。最有可能的是您的过度活跃的工作线程正在扼杀响应能力。把它做好。