Завершение работы службы исполнителя Теперь, как это работает - PullRequest
0 голосов
/ 03 октября 2018

Согласно документу для метода shutdownNow (ExecutorService)

There are no guarantees beyond best-effort attempts to stop
      processing actively executing tasks.  For example, typical
      implementations will cancel via {@link Thread#interrupt}, so any
      task that fails to respond to interrupts may never terminate

У меня есть следующий код:

public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newSingleThreadExecutor(r -> {
            final Thread thread = new Thread(r);
            thread.setDaemon(false);
            return thread;
        });
        service.submit(() -> {
            while (true) {
                Thread.sleep(1000);
                System.out.println("Done: " + Thread.currentThread().isInterrupted());
            }
        });
        Thread.sleep(3000);
        service.shutdownNow();
    }

Это вывод:

Done: false
Done: false

После двух циклов выполнение останавливается.Как shutdownNow прерывает мою работу, у меня просто бесконечный цикл, нет проверки на Thread.currentThread.isInterrupted();

На мой взгляд, shutdownNow вызывает только метод прерывания рабочего потока

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Thread.sleep() проверяет .isInterrupted() и выдает InterruptedException, если оно прервано.Ваша лямбда неявно throws InterruptedException, и поэтому она никогда не достигает вашего System.out.println, когда исполнитель выключается.Вы можете просмотреть источник для ThreadPoolExecutor, чтобы увидеть, как это происходит.

0 голосов
/ 03 октября 2018

Это внутренний механизм, но если вы добавите try nad catch, как показано ниже, вы получите InterruptedException, генерируемый методом сна (поскольку поток уже прерван методом shutdown), поэтому метод shutdown действительно меняет состояние потока.

 public static void main(String[] args) throws InterruptedException {
    ExecutorService service = Executors.newSingleThreadExecutor(r -> {
        final Thread thread = new Thread(r);
        thread.setDaemon(false);
        return thread;
    });

    service.submit(() -> {
        try {
            while (true) {
                Thread.sleep(1000);
                System.out.println("Done: " + Thread.currentThread().isInterrupted());
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    });
    Thread.sleep(3000);
    service.shutdownNow();
}
...