我需要在Java中实现一个线程池(java.util.concurrent),它的线程数在空闲时保持在某个最小值,当任务提交速度快于任务执行完成速度时,线程数增加到一个上限(但不会超过),当所有任务都完成且没有更多任务提交时,线程数将缩小至下限。
你会如何实现这样的功能?我想这应该是一个相当常见的用法场景,但明显 java.util.concurrent.Executors 工厂方法只能创建固定大小或无限制增长的线程池。ThreadPoolExecutor 类提供了 corePoolSize 和 maximumPoolSize 参数,但其文档似乎暗示了要想同时拥有超过 corePoolSize 线程数,唯一的方式是使用有界任务队列,在这种情况下,如果已达到 maximumPoolSize 的线程数,您将得到任务拒绝,需要自己处理?我想出了以下解决方案:
//pool creation
ExecutorService pool = new ThreadPoolExecutor(minSize, maxSize, 500, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(minSize));
...
//submitting jobs
for (Runnable job : ...) {
while (true) {
try {
pool.submit(job);
System.out.println("Job " + job + ": submitted");
break;
} catch (RejectedExecutionException e) {
// maxSize jobs executing concurrently atm.; re-submit new job after short wait
System.out.println("Job " + job + ": rejected...");
try {
Thread.sleep(300);
} catch (InterruptedException e1) {
}
}
}
}
我有没有忽略什么?有更好的方法吗?另外,根据要求,上述代码可能会存在问题,直到至少完成了(我认为)(总作业数)- maxSize
个作业。因此,如果您希望能够将任意数量的作业提交到池中并立即进行而不等待任何作业完成,我不知道您是否可以在没有专用的“作业提交”线程的情况下实现它,该线程管理所需的无界队列以容纳所有已提交的作业。 据我所见,如果您正在为 ThreadPoolExecutor 使用无界队列本身,则其线程计数永远不会超过 corePoolSize。
newCachedThreadPool
不适合你的情况?它会自动关闭不再使用的线程。 - Tudor