我想创建一个ThreadPoolExecutor当它达到其最大大小并且队列已满时,该submit()方法在尝试添加新任务时阻塞.我是否需要为此实现自定义RejectedExecutionHandler,或者是否存在使用标准Java库执行此操作的方法?
我试图使用ThreadPoolExecutor执行许多任务.以下是一个假设的例子:
def workQueue = new ArrayBlockingQueue<Runnable>(3, false)
def threadPoolExecutor = new ThreadPoolExecutor(3, 3, 1L, TimeUnit.HOURS, workQueue)
for(int i = 0; i < 100000; i++)
threadPoolExecutor.execute(runnable)
Run Code Online (Sandbox Code Playgroud)
问题是我很快得到了java.util.concurrent.RejectedExecutionException,因为任务数量超过了工作队列的大小.但是,我正在寻找的所需行为是让主线程阻塞,直到队列中有空间.完成此任务的最佳方法是什么?
我正在使用ExecutorService以方便并发多线程程序.请参考以下代码:
while(xxx) {
ExecutorService exService = Executors.newFixedThreadPool(NUMBER_THREADS);
...
Future<..> ... = exService.submit(..);
...
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,问题是submit()如果所有人NUMBER_THREADS都被占用则不会阻塞.结果是任务队列被许多任务淹没.这样做的结果是,关闭执行服务ExecutorService.shutdown()需要ExecutorService.isTerminated()很长时间(长时间都是假的).原因是任务队列仍然很满.
现在我的解决方法是使用信号量来禁止在任务队列中包含许多条目ExecutorService:
...
Semaphore semaphore=new Semaphore(NUMBER_THREADS);
while(xxx) {
ExecutorService exService = Executors.newFixedThreadPool(NUMBER_THREADS);
...
semaphore.aquire();
// internally the task calls a finish callback, which invokes semaphore.release()
// -> now another task is added to queue
Future<..> ... = exService.submit(..);
...
}
Run Code Online (Sandbox Code Playgroud)
我确信有更好的封装解决方案?