[英]How to manage return values of an unknown amount of Callables using ExecutorService?
我想創建一個具有固定線程池大小的singleton-ExecutorService。 另一個線程將給ExecutorService提供Callables,我想在執行完成后立即(優化)解析Callables的結果。
我真的不確定如何正確執行此操作。 我最初的想法是單例ES中的一種方法,該方法通過“ submit(callable)”向ExecutorService添加了Callable並將其存儲在單例內部的HashMap或ArrayList中。 另一個線程將檢查給定時間間隔內的期貨結果。
但是以某種方式,這種解決方案並不“感覺正確”,並且我在其他地方都沒有找到針對該用例的解決方案,因此我要問你們,在我編寫稍后后悔的東西之前。 您將如何解決這個問題?
我期待您的回復!
您可以使用MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(THREAD_NUMBER));
創建服務並使用番石榴ListenableFuture即時解析結果,您也可以將自行車加長以獲取Listen未來的結果。
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
import java.util.concurrent.*;
public class PostProcExecutor extends ThreadPoolExecutor {
// adjust the constructor to your desired threading policy
public PostProcExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable) {
@Override
protected void done()
{
if(!isCancelled()) try {
processResult(get());
} catch(InterruptedException ex) {
throw new AssertionError("on complete task", ex);
} catch(ExecutionException ex) {
// no result available
}
}
};
}
protected void processResult(Object o)
{
System.out.println("Result "+o);// do your post-processing here
}
}
使用ExecutorCompletionService 。 這樣,您可以在Callable
對象准備好后立即獲得它們的結果。 完成服務的take
方法阻止等待每個任務完成。
這是來自Java文檔的示例:
void solve(Executor e,
Collection<Callable<Result>> solvers)
throws InterruptedException, ExecutionException {
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
use(r);
}
}
您可以使用ExecutorCompletionService來實現它。
以下步驟可以為您提供一些幫助。
使用Runtime.getRuntime()。availableProcessors()填充可用處理器的數量。 讓我們將值保留在變量availableProcessors中。
初始化ExecutorService,例如service = Executors.newFixedThreadPool(availableProcessors)
初始化ExecutorCompletionService,假設Callable的結果是Integer Array Integer [], ExecutorCompletionServicecompleteService = new ExecutorCompletionService(service)
使用completionService.submit提交任務。
使用completionService.take()。get()獲取任務的每個結果(可調用)。
根據上述步驟,您可以獲得所有可調用的結果,並且可以做一些您想做的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.