Java ExecutorService - Завершение задачи монитора / строка состояния - PullRequest
0 голосов
/ 06 февраля 2019

Итак, у меня есть 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 голосов
/ 06 февраля 2019

Здесь работают две вещи.


Во-первых, если мы посмотрим на документацию 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, видимым снаружи, выпришлось бы сделать его атрибутом и доступным через, например, некоторый геттер)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...