Cra*_*lus 36 java concurrency multithreading executorservice java.util.concurrent
如果我们使用ExecutorCompletionService,我们可以提交一系列任务作为Callable
s,并将结果与CompletionService
as进行交互queue
.
但也有在invokeAll
的ExecutorService
,它接受一个Collection
任务,我们得到的名单Future
,以检索结果.
据我所知,有在使用一个或比其他任何好处(除了我们避免for
使用循环invokeAll
,我们将不得不submit
对任务的CompletionService
),基本上他们是有轻微的差别同样的想法.
那么为什么有两种不同的方式来提交一系列任务呢?我是否正确表现他们是相同的?是否有一个比另一个更合适的情况?我想不出一个.
old*_*inb 70
使用a ExecutorCompletionService.poll/take
,您Future
将按完成顺序(或多或少)收到s.使用ExecutorService.invokeAll
,你没有这种力量; 你要么阻止直到全部完成,要么你指定一个超时,之后取消不完整.
static class SleepingCallable implements Callable<String> {
final String name;
final long period;
SleepingCallable(final String name, final long period) {
this.name = name;
this.period = period;
}
public String call() {
try {
Thread.sleep(period);
} catch (InterruptedException ex) { }
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,下面我将演示如何invokeAll
工作:
final ExecutorService pool = Executors.newFixedThreadPool(2);
final List<? extends Callable<String>> callables = Arrays.asList(
new SleepingCallable("quick", 500),
new SleepingCallable("slow", 5000));
try {
for (final Future<String> future : pool.invokeAll(callables)) {
System.out.println(future.get());
}
} catch (ExecutionException | InterruptedException ex) { }
pool.shutdown();
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
C:\dev\scrap>java CompletionExample
... after 5 s ...
quick
slow
Run Code Online (Sandbox Code Playgroud)
使用CompletionService
,我们看到不同的输出:
final ExecutorService pool = Executors.newFixedThreadPool(2);
final CompletionService<String> service = new ExecutorCompletionService<String>(pool);
final List<? extends Callable<String>> callables = Arrays.asList(
new SleepingCallable("slow", 5000),
new SleepingCallable("quick", 500));
for (final Callable<String> callable : callables) {
service.submit(callable);
}
pool.shutdown();
try {
while (!pool.isTerminated()) {
final Future<String> future = service.take();
System.out.println(future.get());
}
} catch (ExecutionException | InterruptedException ex) { }
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
C:\dev\scrap>java CompletionExample
... after 500 ms ...
quick
... after 5 s ...
slow
Run Code Online (Sandbox Code Playgroud)
请注意,时间与程序启动有关,而不是之前的消息.
你可以在这里找到完整的代码.
Gra*_*ray 18
通过使用ExecutorCompletionService
,您可以在每个作业完成时立即得到通知.相比之下,在返回s 集合之前ExecutorService.invokeAll(...)
等待所有作业完成Future
:
// this waits until _all_ of the jobs complete
List<Future<Object>> futures = threadPool.invokeAll(...);
Run Code Online (Sandbox Code Playgroud)
相反,当您使用a时ExecutorCompletionService
,您将能够在每个作业完成后立即获取作业,这允许您(例如)将它们发送到另一个线程池,记录结果等.
ExecutorService threadPool = Executors.newFixedThreadPool(2);
ExecutorCompletionService<Result> compService
= new ExecutorCompletionService<Result>(threadPool);
for (MyJob job : jobs) {
compService.submit(job);
}
// shutdown the pool but the jobs submitted continue to run
threadPool.shutdown();
while (!threadPool.isTerminated()) {
// the take() blocks until any of the jobs complete
// this joins with the jobs in the order they _finish_
Future<Result> future = compService.take();
// this get() won't block
Result result = future.get();
// you can then put the result in some other thread pool or something
// to immediately start processing it
someOtherThreadPool.submit(new SomeNewJob(result));
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23644 次 |
最近记录: |