有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java:我想调整线程池的大小。如何检测CMS收集启动或其他影响可用CPU的系统范围因素?

(这个问题的细节是针对Minecraft的mod。一般来说,这个问题涉及根据系统负载和CPU可用性调整线程池的大小)

我来自Objective C的背景,以及苹果公司用于线程调度的libdispatch(Grand Central Dispatch)

我最关心的问题是,当CMS终身收集运行时,试图减少线程池的大小。有问题的程序(Minecraft)只适用于CMS集合。当其他程序需要大量CPU(特别是屏幕记录器或twitch流)时,减少线程池大小是一个不那么直接但仍然“有趣”的问题

在Java中,我刚刚了解了(深呼吸):
执行器,提供对线程池(固定大小和可调整大小)的访问,缓存线程存在(以避免不断重新创建新线程的开销,或避免根据工作负载编码线程暂停和恢复),
Executor(no s),它是表示“现在是执行此runnable()的时候了”的通用接口,
ExecutorService,根据Executor管理线程池,
ThreadPoolExecutor,它实际管理线程池,并且能够说“这是要使用的最大线程数”

在正常操作下,大约每秒5次,服务器上每个用户将有50个高优先级操作和400个低优先级操作提交到线程池。这是针对高性能机器的

我想做的是:

  1. 与功率较小的机器一起工作。因此,如果一台计算机只有两个内核,而主程序(两个主线程,加上一些次要的辅助线程)已经耗尽了CPU,那么这些后台任务将与主程序和垃圾收集器竞争。在这种情况下,我不想减少后台线程的数量(它可能会保持在2个),但我确实想减少我安排的工作量。因此,这只是“如何检测工作负载何时增加”。我怀疑这只是一个观察执行者执行时使用的工作队列大小的例子。newCachedThreadPool()

但是第一个问题是:我找不到任何东西来返回工作队列的大小!ThreadPoolExecutor()可以返回队列,我可以请求队列的大小,但是newCachedThreadPool()只返回一个ExecutorService,它不允许我查询大小(或者更确切地说,我不知道如何查询)

  1. 如果我有“足够的内核”,我想告诉池使用更多线程。理想情况下,足够使CPU使用率保持在接近最大值。我要运行的大多数任务都是CPU受限的(磁盘I/O将是例外,而不是规则;并发阻塞也将很少见)。但我不想过度安排线程。我如何确定“足够的线程”,而不必检查可用的内核

  2. 例如,如果屏幕录制(或流媒体)激活,其他程序的CPU核心使用率将上升,然后我想减少线程数量;随着线程数量的减少和队列积压的增加,我可以减少添加到队列中的任务量。但我不知道如何检测这个


共 (1) 个答案

  1. # 1 楼答案

    我认为我/我们能给出的最好建议是不要试图“微观管理”线程池中的线程数量。将其设置为与物理内核数量成比例的合理大小。。。别管了。务必提供一些静态调整参数(例如,在配置文件中),但不要让系统自动调整。(在我看来,动态调整比静态调整效果更好的可能性非常小。)

    对于“实时”流媒体,您的成功将取决于总体负载和调度程序的优先级能力,而不是线程数。然而,事实是,标准操作系统上的标准Java SE不适合硬实时,因此,如果超出极限,您的实时性能可能会严重恶化