Со ссылкой на java.util.concurrent пакет и будущий интерфейс я замечаю (если я не ошибаюсь), что способность запустить длинные задачи и быть в состоянии запросить на прогрессе только идет с классом с реализацией SwingWorker.
Это вызывает следующий вопрос:
Существует ли путь, в не-GUI, приложение не-Swing (отображающий консольное приложение), чтобы запустить длинную задачу в фоновом режиме и позволить другим потокам осматривать прогресс? Мне кажется, что нет никакой причины, почему эта возможность должна быть ограничена колебанием / приложения GUI. Иначе единственный доступный вариант, способ, которым я вижу его, состоит в том, чтобы пройти ExecutorService:: отправьте который возвраты будущий объект. Однако основной будущий интерфейс не позволяет контролировать прогресс.
Очевидно, что объект Future подходит только для блокировки и последующего получения результата.
Отправляемый вами объект Runnable или Callable должен либо знать, как обеспечить этот прогресс (процент выполнения, количество попыток, статус (перечисление?) И т. Д.), И предоставить это как вызов API для самого объекта, либо опубликовать в некотором справочном ресурсе (в карте памяти или в базе данных, если необходимо). Для простоты мне нравится сам объект, тем более что вам, скорее всего, понадобится дескриптор (id) для поиска объекта или ссылки на сам объект.
Это означает, что у вас работает 3 потока. 1 для фактической работы, 1 для блокировки в ожидании результата и 1 для потока мониторинга. Последним можно поделиться в зависимости от ваших требований.
Я надеялся, что существует стандартная структура параллелизма, позволяющая следить за ходом выполнения длительной задачи, не требуя от клиентской программы заботиться о правильной организации и синхронизации. Мне казалось, что можно было бы придумать расширенную версию интерфейса Future
, которая бы поддерживала:
public short progress();
в дополнение к обычным методам isDone()
и get()
.
Очевидно, что реализация progress()
должна будет непосредственно опрашивать объект, поэтому, возможно, Future
нужно будет указать как Future
, где CanReportProgress
- это следующий интерфейс:
public interface CanReportProgress {
public short progress();
}
В связи с этим возникает вопрос, зачем нужно проходить через объект Future
, а не вызывать сам объект, чтобы получить прогресс. Я не знаю. Мне нужно будет еще подумать. Можно утверждать, что это ближе к текущему контракту / семантике, согласно которой объект Callable
сам по себе не будет снова доступен программисту-клиенту после вызова ExecutorService::submit
/ execute
.