我需要在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) {
}
}
}
}
我忽略了什么吗?有一个更好的方法吗?此外,根据一个人的要求,上述代码至少(我认为)之前不会完成可能会有问题。 (total number of jobs) - maxSize
工作已经完成。因此,如果您希望能够将任意数量的作业提交到池中并立即进行而无需等待其中任何一个完成,我看不出如何在没有专门的“作业总结”线程的情况下执行此操作保存所有提交的作业所需的无限队列。 AFAICS,如果你为ThreadPoolExecutor本身使用一个无界的队列,它的线程数将永远不会超过corePoolSize。