9

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

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

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

我最初的方法是提高验证线程的优先级,但深入研究后我发现这不是保证行为,算法不应该依赖线程优先级才能正常工作。

有人有任何替代想法吗?谢谢!

4

5 回答 5

1

与其查看常规队列数据结构,不如使用 java.util.concurrent 包的 LinkedBlockingQueue。

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

如果消息到达队列,则将其馈送到等待线程之一(是的,take 确实会阻塞线程,直到有东西要馈送为止)。

链接阻塞队列的 take 方法的 Java API 参考

HTH。

于 2013-03-01T07:29:54.910 回答
0

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

您可以在其他线程执行完工作后让它们进入睡眠状态,并允许其他线程完成它们的工作。我相信 Thread.yield() 会暂停当前线程以给其他线程时间。

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

于 2013-02-26T14:37:34.130 回答
0

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

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

于 2013-02-26T14:40:57.813 回答
0

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

于 2013-02-26T14:41:30.277 回答
0

似乎您需要利用条件变量。窥视将占用 CPU 周期。

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

于 2013-02-27T15:19:46.060 回答