Java中Do-While循环的ExecutorService



我是并发的新手,我正试图实现一个do-while循环的执行器服务并发。但是我总是碰到RejectedExecutionException

下面是我的示例代码:
do {    
    Future<Void> future = executor.submit(new Callable<Void>() {
    @Override        
    public Void call() throws Exception {
        // action
        return null;
    }
    });
    futures.add(future);
    executor.shutdown();
    for (Future<Void> future : futures) {
        try {
            future.get();
        }
        catch (InterruptedException e) {
            throw new IOException(e)
        }          
    } 
}
while (true);

但这似乎不正确。我想我在错误的地方呼吁关闭。谁能帮我正确地实现Executor Service in a do-while环?谢谢。

ExecutorService.shutdown()停止ExecutorService接受任何作业。它应该在你完成提交作业时被调用。

future .get()也是一个阻塞方法,这意味着它将阻塞当前线程的执行,并且循环的下一次迭代将不会继续,除非这个future(调用get的future)返回。这将在每次迭代中发生,这使得代码是非并行的。

你可以使用CountDownLatch来等待所有的作业返回。

正确代码如下:

final List<Object> results = Collections.synchronizedList(new ArrayList<Object>());
final CountDownLatch latch = new CountDownLatch(10);//suppose you'll have 10 futures
do {
    Future<Void> future = executor.submit(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            // action
            latch.countDown();//decrease the latch count
            results.add(result); // some result
            return null;
        }
    });
    futures.add(future);
} while (true);
executor.shutdown();
latch.await(); //This will block till latch.countDown() has been called 10 times.
//Now results has all the outputs, do what you want with them.

如果你使用的是Java 8那么你可以看看这个答案https://stackoverflow.com/a/36261808/5343269

您是对的,shutdown方法没有在正确的时间被调用。在shutdown被调用后,ExecutorService将不接受任务(除非你实现了自己的版本)。

您应该在已经将所有任务提交给执行器之后调用shutdown,因此在本例中,在do-while循环之后的某个地方。

来自ThreadPoolExecutor文档:

拒绝任务

在execute(Runnable)方法中提交的新任务将在Executor被关闭时被拒绝,并且当Executor为最大线程和工作队列容量使用有限界限并且饱和时。

无论哪种情况,execute方法都调用RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler

从你的代码中,很明显你首先调用shutdown(),然后提交任务。

另一方面,请参考以下相关的SE问题,了解关闭ExecutorService的正确方法:

ExecutorService's shutdown()不会等到所有线程都完成

相关内容

  • 没有找到相关文章

最新更新