我正在寻找一个ExecutorService
按需创建线程达到预定义的限制,并在保持活动时间后销毁空闲线程。
以下构造函数创建一个具有固定线程数的ThreadPoolExecutor
:
// taken from Executors.newFixedThreadPool()
new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
所以我尝试用这种方式创建ExecutorService
:
// taken from Executors.newCachedThreadPool()
new ThreadPoolExecutor(0, nThreads,
CACHED_POOL_SHUTDOWN_DELAY, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
但是,当nThreads
正在使用时,Executor
不会按预期运行,RejectedExecutionException
不会将新任务排入队列,但会抛出Executor
。我知道我可以为此实现一个处理程序,但它对我没有帮助。
如何创建前面描述的{{1}}?
答案 0 :(得分:1)
如果新任务无法排队,则会创建一个新线程,除非您已达到最大核心池大小。在您的情况下,队列一次只能包含一个任务,因此如果您足够快地提交任务,则达到最大池大小并获得异常。
它适用于CachedThreadPool,因为最大核心池大小很大(Integer.MAX_VALUE
)。
您需要使用不同的队列,例如固定线程池示例中的新LinkedBlockingQueue
。
附注:检查实施文档有助于了解详细信息。特别是,execute
类的ThreadPoolExecutor
方法具有:
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
答案 1 :(得分:1)
我在that post找到了一种方法,完全符合我的需要 @assylias我认出你的答案并改变了队列实施。
现在我的代码看起来像这样:
parallelExecutor = new ThreadPoolExecutor(nThreads, nThreads,
CACHED_POOL_SHUTDOWN_DELAY, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
parallelExecutor.allowCoreThreadTimeOut(true); // this is the magic
它的工作方式类似于固定的线程池,但允许这些核心超时。