java - 如何使用几个线程完成大量作业,并为每个线程提供相同的超时完成时间?

标签 java future executorservice executor

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

  1. 我有 1000 个网址可供下载数据,以便将其用于后期处理(例如,计算一些统计数据)。 我实际上并不需要成功完成所有下载,但需要尽可能多。
  2. 我认为某些位置可能不可用,要么没有响应任何有值(value)的内容(例如 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());
}   

看起来我正在努力实现一些目标。但它既不会为每次下载提供相同的超时时间,也不会正确取消 future 。那么,正确的解决方案是什么?

最佳答案

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

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

关于java - 如何使用几个线程完成大量作业,并为每个线程提供相同的超时完成时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42021951/

相关文章:

java - 更改 ScheduledThreadPoolExecutorService 的延迟而不终止服务

java - 在java中模拟ExecutorService invokeAll方法

类函数内部的Java泛型重新定义

scala - 在 scala Future 中执行类似 DAG 的操作

java - future 与可完成的 future ?对于这个用例 Completablefuture 会有什么不同吗?

rust - rust 铸就 future 的沉沦

java - 从执行程序服务停止正在运行的线程的优雅方法是什么

java - Selenium 网络驱动程序 : finding all elements with similar id

java - MQ - 获取多实例 MQ 管理器连接列表

java,使用字典进行zip?