ExecutorService - отключение основного потока - PullRequest
0 голосов
/ 19 октября 2018

У меня есть код ниже, вызываемый из основного потока, использующий пул ExecutorService и запускающий поток для обработки каждого найденного файла.Я пытаюсь понять поведение ExecutorService, когда основной поток завершается командой kill.Что происходит с порожденными нитями?Их сразу же убивают или они заканчивают работу после того, как закончили свою работу?

Также есть ли лучший / более безопасный способ написания приведенного ниже фрагмента, особенно если я хочу выполнить эту часть в бесконечном цикле, напримерждет, когда файлы будут сброшены во входной каталог и назначат потоки для их обработки?В таком случае я должен создавать новый пул и .awaitTermination в каждой итерации цикла?

Большое спасибо

ExecutorService executorService = Executors.newFixedThreadPool(maxThreads);

        for (File inputFile : inputDir.listFiles()) {   
        if (inputFile.isFile())     
                executorService.submit(new MyRunnable(inputFile));      
        }

        executorService.shutdown();
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);

Ответы [ 2 ]

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

, когда основной поток завершается командой kill.Что происходит с порожденными нитями?

Основной поток не уничтожается (если вы имеете в виду kill <pid> из командной строки), но JVM уничтожается, и в этом случае уничтожение затрагивает все запущенные потоки.Вы можете настроить обработчики выключения, которые будут срабатывать при получении сигнала уничтожения (не kill -9).См .: https://stackoverflow.com/a/2541618/179850

В таком случае я должен создавать новый Пул и .awaitTermination в каждой итерации цикла?

Нет.То, что я хотел бы сделать, это отправить ваши задания в пул потоков, запущенный вне цикла, но сохранить Future s, возвращаемые executorService.submit(...) в коллекции внутри цикла.Вы можете сделать что-то вроде следующего, чтобы дождаться завершения каждого из заданий.Здесь есть исключения для обработки:

// this is all inside of the loop with the executorService created outside of loop
List<Future<?>> futures = new ArrayList<>();
for (File inputFile : inputDir.listFiles()) {   
    if (inputFile.isFile())     
         futures.add(executorService.submit(new MyRunnable(inputFile)));      
    }
}
// now we go back and wait for the jobs to finish
for (Future<?> future : futures) {
    // this waits for each job to finish
    // it throws some exceptions that you'll need to catch and handle
    future.get();
}
0 голосов
/ 19 октября 2018

Если основной поток чем-то закончен, сбой, сон ... это не влияет на другие потоки, пока ваша логика не связана с ним.Они независимы и будут продолжать выполнять эту работу за вас (до тех пор, пока они не являются демоническими потоками, которым JVM не назначает приоритеты, и процесс будет завершен, если останутся только демонические потоки).Вы указали:

завершается командой kill

, и если это означает уничтожение PID / уничтожение процесса JVM, тогда да, все потоки будут закрыты с помощьюсамо приложение.

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