Java 中 Do-While 循环的 ExecutorService

ExecutorService for Do-While Loop in Java

我是并发的新手,我正在尝试为 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 循环。谢谢

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

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

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

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

您可以使用 CountDownLatch 等待所有作业到 return。

以下是正确的代码。

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,那么您可以查看此答案

来自 ThreadPoolExecutor 文档:

Rejected tasks

New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.

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

从您的代码中可以清楚地看出您是先调用 shutdown() 然后再提交任务。

换句话说,请参阅此相关的 SE 问题以了解正确的关机方式 ExecutorService