[英]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.