Java中Do-While循环的ExecutorService

时间:2016-08-12 18:35:27

标签: java multithreading try-catch 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循环。感谢。

3 个答案:

答案 0 :(得分:3)

ExecutorService.shutdown()阻止ExecutorService接受更多工作。当你完成提交工作时应该调用它。

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

您可以使用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

答案 1 :(得分:1)

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

在您已经将所有任务提交给执行者之后,您应该致电shutdown,所以在这种情况下,在do-while循环之后的某个地方。

答案 2 :(得分:0)

来自ThreadPoolExecutor文档:

  

拒绝的任务

     

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

在任何一种情况下,execute方法都会调用RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler

从您的代码中可以清楚地看到您先调用shutdown()并稍后提交任务。

另请注意,请参阅此相关的SE问题,了解关闭ExecutorService的正确方法:

ExecutorService's shutdown() doesn't wait until all threads will be finished