Java ExecutorService-监视任务完成/状态栏

时间:2019-02-05 22:38:53

标签: java android future executorservice blocking

所以我现在有一个ExecutorService成功地成功阻止并线性运行。我的麻烦是,我正在尝试添加状态更新,但我不知道如何让期货一次结算一个项目。看来,到我的Future <>中的第一个项目准备就绪时,最后一个项目也准备就绪了。我希望找到一个我可以知道executorService剩余/总计多少任务的地方,以便我可以计算一个简单的百分比指标。请注意,我打算回收执行器,并且不想将其关闭。

ExecutorService updateService = Executors.newSingleThreadExecutor();
Callable<String> callHour = () -> {
  //doStuff, unaware of total number of hourCalls
  return "done";
};
private void startMe(int hours){
  List<Future<String>> futureHours;
  List<Callable<String>> hourCalls = new ArrayList<>(hours);
    for (int hour = 0; hour < hours; ++hour) {
      hourCalls.add(callHour); //queue list (not running yet)
    }
    try {
      //executes queue and blocks thread
      futureHours = updateService.invokeAll(hourCalls);
      futureHours.get(0).get();//performs blocking
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

1 个答案:

答案 0 :(得分:2)

这里有两件事在起作用。


首先,如果我们看一下the documentation of ExecutorService#invokeAll(...),我们会看到它返回了

  

[...]列出拥有其状态和结果的期货完成后的列表。 [...]

(我加强调)

您很可能想改用Executor#submit(...)


第二,您不能保证首先执行与futureHours.get(0)关联的任务。我建议将Future#isDone()与其他逻辑结合使用:

private void startMe(int hours) {
  [...]
  try {
    [...]
    ArrayList<Future<String>> futureHoursDone = new ArrayList<>();
    final int numTasks = futureHours.size();
    int done = 0;
    double percentageDone = 0.0d;
    while (futureHours.isEmpty() == false) {
      for (int index = 0; index < futureHours.size(); ++index) {
        Future<String> futureHour = futureHours.get(index);
        if (futureHour.isDone()) {
          futureHours.remove(index);
          futureHoursDone.add(futureHour);
          --index;
          ++done;
          percentageDone = done / (double) numTasks;
        }
      }
    }
  } catch (Exception e) {
    // TODO: don't forget to HCF (https://en.wikipedia.org/wiki/Halt_and_Catch_Fire) :)
    e.printStackTrace();
  }
}

(这是一个粗略的草图。要使进度percentage对外部可见,您必须将其设为一个属性,并可以通过例如一些吸气剂进行访问)