Java Executors 不排队某些任务
Posted
技术标签:
【中文标题】Java Executors 不排队某些任务【英文标题】:Java Executors not queue some task 【发布时间】:2022-01-11 02:06:49 【问题描述】:我找不到任何满足我要求的执行者。 我想要一个带有 corePoolSize、maximumPoolSize 和 BlockingQueue 的 ExecutorService;
调用execute函数时,像往常一样使用核心线程,如果核心线程正在使用,则将任务放入队列,如果队列已满,则创建新线程,直到达到maximumPoolSize。这是 ThraPoolExecutor 的标准行为。 ThreadPoolExecutor
在这部分之前一切都很好。我可以用这个规范创建一个 ThreadPoolExecutor。
但是对于某些任务,如果核心线程已满,请不要将它们排队创建一个新线程。但是如果 maximumPoolSize 达到然后排队任务但把任务放在第一位。
如何实现这样的需求,有没有可以使用的内置功能。
【问题讨论】:
这是什么意思? “......然后将任务排队,但将任务放在第一位。” @swpalmer 我已经编辑了问题。 您希望任务优先,以便最后提交的任务是下一个计划执行的第一个任务? LIFO? @BasilBourque 是的,但仅适用于某些任务,例如为它们调用 executeNow() 函数,如果 maxPoolSize 未满则使用它们,否则将任务置于队列顶部。 哪个标准应该告诉执行者某个任务是特殊任务? 【参考方案1】:不,我知道没有执行器服务优先于其他任务运行的任务。
多个执行器服务
但是您可以很容易地自己有效地做到这一点。建立多个执行器服务。一个用于低优先级任务,另一个用于高优先级任务。
在下面的例子中,我们假设一台 12 核的机器没有过度负担。我们将一千个任务分配给低优先级服务。我们将三个任务分配给高优先级服务。三项重要任务将立即安排执行。
ExecutorService highPriorityExecutorService = Executors.newFixedThreadPool( 5 ) ;
ExecutorService lowPriorityExecutorService = Executors.newFixedThreadPool( 3 ) ;
顺便说一句,如果该团队成功,Project Loom 可能会成为您的问题。性能可能会得到如此显着的提升,以至于在某些情况下,您可能不再需要确定任务的优先级。
Project Loom 将virtual threads(又名fibers)添加到Java 的并发设施中。虚拟线程运行成本低,内存和 CPU 使用效率更高,普通计算机可能能够处理数百万个线程。
JVM 将许多虚拟线程调度到由主机操作系统管理的几个“真实”线程上。任何其工作块被立即搁置(“停放”)的虚拟线程,因为另一个虚拟线程被安排立即执行。在这种情况下,底层运营商线程(主机操作系统线程)不会阻塞。目标是在任何虚拟线程挂起时保持主机线程持续高效地工作。
使用 Project Loom 技术的 OpenJDK 实验版本现已推出,基于早期访问 Java 18。
【讨论】:
您的意思可能是“基于早期访问 Java 18”。但是单独的虚拟线程不会优先处理任务。只要具有更高优先级的任务存在(并运行),它仍然需要一个阻止某些任务的构造。 @Holger 是的,我的意思是 18;谢谢,修好了。至于虚拟线程,并不是它们不直接提供任务的优先级。我的意思是,性能可能会得到如此显着的提升,以至于在某些情况下,优先考虑的需求可能会消失。 这适用于任务可能阻塞(I/O 等)的情况。然后,随着虚拟线程的协作,Loom 不再需要限制线程数。对于计算密集型任务,仍然会有所不同,哪些任务会消耗 CPU 时间…… @Holger 是的,但我希望 CPU 绑定的基于 Java 的应用程序不会进行网络调用、数据库调用、日志记录和存储中的文件访问,这种情况非常罕见。然后,此类应用程序将使用 Java 中已经存在的现有并发功能,例如此答案中显示的一对高/低优先级执行器服务。以上是关于Java Executors 不排队某些任务的主要内容,如果未能解决你的问题,请参考以下文章
Executors框架二 ScheduledThreadPoolExecutor线程池