我需要一次执行一定数量的任务4,就像这样:
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
//...wait for completion somehow
当所有这些都完成后,我如何得到通知?现在我想不出比设置一些全局任务计数器更好的方法,并在每个任务结束时减少它,然后在无限循环中监视这个计数器变成0;或获取一个期货列表,并在无限循环监视器isDone为所有它们。不涉及无限循环的更好的解决方案是什么?
谢谢。
你可以在这个Runner类上调用waitTillDone():
Runner runner = Runner.runner(4); // create pool with 4 threads in thread pool
while(...) {
runner.run(new MyTask()); // here you submit your task
}
runner.waitTillDone(); // and this blocks until all tasks are finished (or failed)
runner.shutdown(); // once you done you can shutdown the runner
在调用shutdown()之前,您可以重用这个类并多次调用waitTillDone(),而且您的代码非常简单。你也不需要预先知道任务的数量。
要使用它,只需将gradle/maven compile 'com.github.matejtymes:javafixes:1.3.1'依赖项添加到你的项目中。
详情请点击这里:
https://github.com/MatejTymes/JavaFixes
有点晚了,但为了完成…
不要“等待”所有的任务都完成,你可以用好莱坞的原则来思考,“不要给我打电话,我会给你打电话”——当我完成的时候。
我认为结果代码更优雅…
番石榴提供了一些有趣的工具来实现这一点。
一个例子:
将ExecutorService包装成ListeningExecutorService:
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
提交一个可调用对象的集合来执行::
for (Callable<Integer> callable : callables) {
ListenableFuture<Integer> lf = service.submit(callable);
// listenableFutures is a collection
listenableFutures.add(lf)
});
现在最重要的部分:
ListenableFuture<List<Integer>> lf = Futures.successfulAsList(listenableFutures);
附加一个回调到ListenableFuture,当所有future完成时,你可以使用它来得到通知:
Futures.addCallback(lf, new FutureCallback<List<Integer>> () {
@Override
public void onSuccess(List<Integer> result) {
// do something with all the results
}
@Override
public void onFailure(Throwable t) {
// log failure
}
});
这也提供了一个好处,一旦处理完成,您就可以在一个地方收集所有的结果……
更多信息请点击这里
你应该使用executorService.shutdown()和executorService。awaitTermination方法。
示例如下:
public class ScheduledThreadPoolExample {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
executorService.scheduleAtFixedRate(() -> System.out.println("process task."),
0, 1, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(10);
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
}
}