CPU负载中的Java多线程
对于运行多个Java线程的应用程序,我有点问题。 应用程序运行多个工作线程,这些线程不断地查看输入队列,如果队列中有消息,它们就会将其拉出并处理
在这些工作线程中,还有另一个验证线程计划在固定的时间段执行一项检查,以查看主机(应用程序在其上运行)是否仍处于运行应用程序的“良好状态”。该线程更新一个AtomicBoolean
值,工作线程在开始窥视主机是否正常之前,会对该值进行验证
我的问题是,在CPU负载较高的情况下,负责验证的线程将花费更长的时间,因为它必须与所有其他线程竞争。如果AtomicBoolean
在一段时间后没有得到更新,它会自动设置为false,这会造成严重的瓶颈
我最初的方法是增加验证线程的优先级,但深入研究后,我发现这不是一种保证的行为,算法不应该依赖线程优先级来正确运行
有人有别的想法吗?谢谢
# 1 楼答案
你是否在使用Executor框架(来自Java的并发包)?如果不是的话,试试看。您可以尝试对验证线程使用ScheduledExecutorService
# 2 楼答案
一种老派的控制工作速率的方法,根本不使用健康检查线程(因此绕过这些问题),就是在队列长度超过100时阻止或拒绝添加到队列中的请求。这会对生成负载的客户机施加动态背压,当工作线程负载过大时,会减慢它们的速度
这种方法被添加到Java 1.5库中,请参见Java。util。同时发生的排队。如果队列已满,它的put(o)方法将阻塞
# 3 楼答案
不要窥探常规队列数据结构,而是使用java。util。并发包的LinkedBlockingQueue
你可以做的是,运行一个线程池(你可以使用executer服务的固定线程池,即你选择的多个工作线程)并执行LinkedBlockingQueue。拿()
如果消息到达队列,它将被送入一个等待的线程(是的,take会阻止该线程,直到有东西要送入)
Java API Reference for Linked Blocking Queue's take method
嗯
# 4 楼答案
似乎你需要利用条件变量。偷看需要cpu周期
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html