简体   繁体   English

Java中的Do-While循环的ExecutorService

[英]ExecutorService for Do-While Loop in Java

I am new to concurrency and I was trying to implement executor service concurrency for a do-while loop. 我是并发的新手,我正在尝试为do-while循环实现执行程序服务并发。 But I always run into RejectedExecutionException 但是我总是碰到RejectedExecutionException

Here is my sample code: 这是我的示例代码:

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);

But this seems incorrect. 但这似乎不正确。 I think I am calling the shutdown at the wrong place. 我想我在错误的地方打电话给关机了。 Can anyone please help me implement Executor Service in a do-while loop correctly. 谁能帮助我Executor Service in a do-while循环中正确实现Executor Service in a do-while Thanks. 谢谢。

ExecutorService.shutdown() stops the ExecutorService from accepting anymore jobs. ExecutorService.shutdown()阻止ExecutorService接受更多作业。 It should be called when you're done submitting jobs. 完成提交作业后应调用它。

Also Future.get() is a blocking method, which means it will block the execution of current thread and next iteration of loop will not continue unless this future (on which the get is called) returns. 另外, Future.get()是一种阻塞方法,这意味着它将阻塞当前线程的执行,除非下一次返回(调用get的) Future ,否则循环的下一次迭代将不会继续。 This will happen in every iteration, which makes the code non parallel. 这将在每次迭代中发生,这会使代码变得不并行。

You can use a CountDownLatch to wait for all the jobs to return. 您可以使用CountDownLatch等待所有作业返回。

Following is the correct code. 以下是正确的代码。

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.

Also if you're working with Java 8 then you can take a look at this answer https://stackoverflow.com/a/36261808/5343269 另外,如果您使用的是Java 8,则可以查看以下答案https://stackoverflow.com/a/36261808/5343269

You're right, the shutdown method is not being called at the correct time. 没错,没有在正确的时间调用shutdown方法。 The ExecutorService will not accept tasks after shutdown is called (unless you implement your own version that does). 调用shutdown后, ExecutorService将不接受任务(除非您实现自己的版本)。

You should call shutdown after you've already submitted all tasks to the executor, so in this case, somewhere after the do-while loop. 在将所有任务提交给执行器之后,应该调用shutdown ,因此在这种情况下,请在do-while循环之后的某个位置进行。

From ThreadPoolExecutor documentation: 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(Runnable)中提交的新任务。

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

From your code, it's clearly evident that you are calling shutdown() first and submitting the tasks later. 从代码中可以明显看出,您先调用shutdown()然后再提交任务。

On a different note, refer to this related SE question for right way of shutting down ExecutorService : 另一方面,请参考此相关的SE问题以关闭ExecutorService正确方法:

ExecutorService's shutdown() doesn't wait until all threads will be finished ExecutorService的shutdown()不会等待所有线程完成

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM