Java执行程序:等待任务终止.

Raf*_*ffo 15 java concurrency multithreading executorservice

我需要提交一些任务,然后等待所有结果,直到所有结果都可用.它们中的每一个都添加了Stringa Vector(默认情况下是同步的).然后我需要为Vector中的每个结果启动一个新任务,但是只有当所有先前的任务都停止了它们的工作时我才需要这样做.

我想使用Java Executor,特别是我尝试使用Executors.newFixedThreadPool(100)以便使用固定数量的线程(我有一个可变数量的任务,可以是10或500)但我是执行者的新手,我不知道如何等待任务终止.这就像我的程序需要做的伪代码:

ExecutorService e = Executors.newFixedThreadPool(100);
while(true){

/*do something*/

for(...){
<start task>
}

<wait for all task termination>

for each String in result{
<start task>
}

<wait for all task termination>
}
Run Code Online (Sandbox Code Playgroud)

我不能做e.shutdown,因为我有一段时间(真的),我需要重用executorService...

你能帮助我吗?你能给我一个关于java执行器的指南/书吗?

oxb*_*kes 21

ExecutorService为您提供了一种同时执行多个任务并获取Future对象集合的机制(表示任务的异步计算).

Collection<Callable<?>> tasks = new LinkedList<Callable<?>>();
//populate tasks
for (Future<?> f : executorService.invokeAll(tasks)) { //invokeAll() blocks until ALL tasks submitted to executor complete
    f.get(); 
}
Run Code Online (Sandbox Code Playgroud)

如果你有RunnableS的,而不是CallableS,您可以轻松地将一个RunnableCallable<Object>使用方法:

Callable<?> c = Executors.callable(runnable);
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉挖掘旧帖子,但我没有看到调用f.get(); invokeAll()本身就是阻塞的,所以除非你对结果感兴趣(你的代码不是这样),否则不需要调用get(). (4认同)

Jon*_*nik 14

你能给我一个关于java执行器的指南/书吗?

我可以回答这一部分:

Brian Goetz的实践中 Java Concurrency(与Tim Peierls, Joshua Bloch,Joseph Bowbeer,David Holmes和 Doug Lea一起)很可能是你最好的选择.

不仅仅涉及执行程序,而是涵盖java.util.concurrent了一般的包,以及基本的并发概念和技术,以及一些高级主题,如Java内存模型.


Ada*_*ski 14

而不是直接提交Runnables或Callables Executor并存储相应的Future返回值,我建议使用CompletionService实现来Future 在完成时检索每个.这种方法将任务的生成与已完成任务的消耗分离,允许例如在一段时间内在生产者线程上发起新任务.

Collection<Callable<Result>> workItems = ...
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletionService<Result> compService = new ExecutorCompletionService<Result>(executor);

// Add work items to Executor.
for (Callable<Result> workItem : workItems) {
  compService.submit(workItem);
}

// Consume results as they complete (this would typically occur on a different thread).
for (int i=0; i<workItems.size(); ++i) {
  Future<Result> fut = compService.take(); // Will block until a result is available.
  Result result = fut.get(); // Extract result; this will not block.
}
Run Code Online (Sandbox Code Playgroud)