如何在几个线程给每个线程相同的超时时间的情况下完成大量作业



我试图实现的一个想法如下。

  1. 我有1000个url可以下载数据,用于后期处理(比如计算一些统计数据)。我真的不需要所有的下载都能成功完成,但要尽可能多
  2. 我假设有些位置可能不可用,要么没有任何有价值的响应(例如,HTTP 503),要么处理请求需要超过TO=10秒的时间
  3. 我有T=5个线程并行处理url,每个线程都有相等的超时to
  4. 一旦完成(我预计会发生的事情比to早得多),我就会汇总一些统计数据(这是一个非常快速的操作),并开始下一次下载(如果有的话)

到目前为止,我提出的解决方案是

ExecutorService executorService = Executors.newFixedThreadPool(T);
ExecutorCompletionService<MyResult> completionService = new ExecutorCompletionService<>(executorService);
urls.forEach(url -> {
Callable<MyResult> callable = () -> new MyResult(url);
completionService.submit(callable);
}); 
for (int i = 0; i < urls.size(); i++) {
Future<MyResult> resultFuture = completionService.poll(TO, TimeUnit.SECONDS);
if (resultFuture == null)
continue;
MyResult myResult = resultFuture.get();
myAggregate(myResult.getRate());
}   

这看起来有点像我正在努力实现的目标。但例如,它既没有给每次下载提供相同的超时时间,也没有正确地取消Futures。那么,正确的解决方案是什么?

尝试使用invokeAll方法,只需将Callables放入List中,然后在ExecutorService上调用invokeAll(),将其作为第二个和第三个参数超时。

executorService.invokeAll(callableList, 20, TimeUnit.SECONDS);

相关内容

  • 没有找到相关文章

最新更新