具有可抢占线程队列的多线程java执行器
我正在寻找一个java线程池,它不会同时运行比系统中的内核更多的线程。此服务通常由ThreadPoolExecutor使用BlockingQueue提供
但是,如果计划执行一个新线程,我希望新线程先占一个已经运行的线程,并将先占线程(处于挂起状态)添加到任务队列中,以便在新线程完成后立即恢复
有什么建议吗
你可以在下面搜索框中键入要查询的问题!
我正在寻找一个java线程池,它不会同时运行比系统中的内核更多的线程。此服务通常由ThreadPoolExecutor使用BlockingQueue提供
但是,如果计划执行一个新线程,我希望新线程先占一个已经运行的线程,并将先占线程(处于挂起状态)添加到任务队列中,以便在新线程完成后立即恢复
有什么建议吗
# 1 楼答案
我将创建ThreadPoolExecutor的子类
在设置ThreadPoolExecutor时,您希望将
corePoolSize
和maximumPoolSize
设置为Runtime.getRuntime().availableProcessors()
(查看Executors.newFixedThreadPool()
以了解其工作原理)接下来,您要确保您的
Queue
也实现了Deque
LinkedBlockingDeque
就是一个例子,但是你应该四处看看哪一个最适合你。一个Deque
允许您获得堆栈式的后进先出行为,这正是您想要的因为所有(
submit()
,invokeAll()
)都是通过execute()
进行的,所以您需要重写此方法。基本上按照您上面描述的操作:检查是否所有线程都在运行。如果不是,只需在可用线程上启动新的runnable即可。如果所有线程都已经在运行,那么您需要找到运行最早的runnable的线程,停止runnable,将runnable重新排入某个位置(可能在开始时?),然后开始新的runnable
# 2 楼答案
ThreadPoolExecutor的想法是避免所有与创建和销毁线程相关的昂贵操作。如果您绝对坚持抢占正在运行的任务,那么您将无法从默认API中获得这一点
如果您愿意让正在运行的任务完成,而只抢占尚未开始执行的任务,那么您可以使用BlockingQueue实现,它的工作方式类似于堆栈(LIFO)
通过使用具有不同线程优先级的不同执行器,您还可以让任务“抢占”其他任务。本质上,如果操作系统支持时间切片,那么高优先级的执行器将获得时间切片
否则,您需要一个管理执行的自定义实现。您可以使用SynchronousQueue并让P个工作线程等待它。如果客户端调用execute和SynchronousQueue。如果提供失败,则必须创建一个特殊的工作线程,该线程将捕获其他线程中的一个,并在执行之前将其标记为停止,然后在执行之后再次将其标记为恢复