ExecutorService: получить список отправленных задач и отменить все задачи, не выключая исполнителя - PullRequest
2 голосов
/ 04 октября 2019

У меня есть ExecutorService, для которого я отправляю задачи:

private final ExecutorService CUSTOM_POOL = Executors
            .newCachedThreadPool();
private Queue<Future<?>> customTasksHandles;
private boolean started;

private Runnable task = new Runnable()  {
        @Override
        public void run()  {
            if (!started)  {return;}
            ...
            customTasksHandles.add(CUSTOM_POOL.submit(new CustomTask(customData)));
            ...
        }
}

Мне нужно создать функции public void stop() и public void start(). Функция stop() будет future.cancel() для каждой задачи, которая была отправлена ​​исполнителю, тогда как start() снова начнет запускать task Runnable.

public void stop()  {
  ...
  Future customTasksHandle= customTasksHandles.poll();
        while (customTasksHandle!=null) {
            customTasksHandle.cancel(true);
            customTasksHandle=locationTasksHandles.poll();
        }
   ...
   started = false;
}

public void start()  {started = true;}

Я пытался простоCUSTOM_POOL.shutdown(), однако, кажется, что невозможно представить новые задачи позже, после вызова start(). Кажется, что единственный способ - перебрать все отправленные задачи и вызвать .cancel() для каждой.

Однако как получить все отправленные задачи, не добавляя каждую задачу в список / очередь при отправке? Есть ли лучший способ сделать это, кроме как выше? Я надеялся на метод List<Future> submittedTasks = CUSTOM_POOL.getAllSubmittedTasks(), но, похоже, его нет. Интересно, что методы .shutdown() и invoke() возвращают List<Future>, но имеют побочные эффекты.

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Вы можете достичь этого, используя Future, создать start метод, который принимает Runnable и возвращает Future

public Future<?> start(Runnable run) {
    return CUSTOM_POOL.submit(run);
}

Вы можете сохранить все эти Future в Listили Map, чтобы вы могли отменить все, что вам нужно, используя пользовательский stop метод

public void stop(Future<?> future) {
    future.cancel(true);
}

Пример

public class TestMain {

private final ExecutorService CUSTOM_POOL = Executors
        .newCachedThreadPool();

public static void main(String[] args) {
  //custom logic

   }

public Future<?> start(Runnable run) {
    return CUSTOM_POOL.submit(run);
     }

public void stop(Future<?> future) {
    future.cancel(true);
     }
}

Future

Пытается отменить выполнение этого задания. Эта попытка потерпит неудачу, если задача уже завершена, уже отменена или не может быть отменена по какой-либо другой причине. Если успешно, и эта задача не была запущена при вызове отмены, эта задача никогда не должна выполняться. Если задача уже запущена, параметр mayInterruptIfRunning определяет, следует ли прерывать поток, выполняющий эту задачу, при попытке остановить задачу.

1 голос
/ 04 октября 2019

Как вы можете видеть здесь , вы можете использовать метод shutdownNow (), чтобы остановить и извлечь всю задачу, ожидающую выполнения. Если вам нужно просто остановить («приостановить») обработку задачи и продолжить с ней, вы, скорее всего, захотите следить за состоянием тактов, а когда вы ставите паузу и отменяете задачу, вы можете повторно отправить возвращенную задачу. с помощью метода shutdownNow () и того, который выполняется в момент остановки. Следует учитывать, что для остановки потоков пул может вызывать прерывание потока, поэтому, если вы выполняете какую-то разумную работу, вы должны позаботиться об этом должным образом. Для потоков нет паузы и паузы. отметьте это

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