Приложение ThreadPoolExecutor не завершается

Это очень простое приложение печатает «Hello», но не завершает работу. Я не вижу абсолютно никаких причин, почему это должно быть.

JavaDoc, завершение раздела, говорит, что

Пул, на который больше нет ссылок в программе И в котором нет оставшихся потоков, будет автоматически закрыт.

tpe явно не упоминается, это означает, что поток не заканчивается. Но я не понимаю, почему. Может ли кто-нибудь объяснить?

Решение в этом случае состоит в том, чтобы вызвать shutdown() в конце main, но мое фактическое приложение более сложное. Новая работа генерируется внутри Runnables, поэтому я не знаю, когда именно все будет обработано.

Итак, мне нужно выяснить, когда вызывать выключение? Или можно как-то указать, что когда очередь tpe пуста, он должен сам отключаться?

public class JavaApplication5 {
public static void main(String[] args) {
    ThreadPoolExecutor tpe = new ThreadPoolExecutor(5, 15, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
    tpe.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello");
        }
    });
}

}


person adekcz    schedule 04.06.2015    source источник
comment
Продолжайте читать до конца. Вы должны убедиться, что неиспользуемые потоки умирают.   -  person Sotirios Delimanolis    schedule 04.06.2015


Ответы (2)


Когда ваш основной метод завершает работу, у вашего исполнителя не осталось задач, но все еще есть запущенные потоки.

Установите флаг allowCoreThreadTimeout в true перед отправкой любых задач. Затем, когда ваш исполнитель выходит за пределы области действия, поскольку основной метод завершается, и все ваши задачи завершаются, потоки будут завершены. См. Завершение в документации по API ThreadPoolExecutor. :

Пул, на который больше нет ссылок в программе И в котором нет оставшихся потоков, будет автоматически закрыт. Если вы хотите, чтобы пулы, на которые нет ссылок, освобождались, даже если пользователи забыли вызвать shutdown(), то вы должны сделать так, чтобы неиспользуемые потоки в конечном итоге умирали, установив соответствующее время поддержания активности, используя нижнюю границу нуля основных потоков и/или установка allowCoreThreadTimeOut (логическое значение).

person Nathan Hughes    schedule 04.06.2015

Или можно как-то указать, что когда очередь tpe пуста, чем выключается сам? - Нет. Даже если бы это было возможно, то очередь tpe была бы пустой при первом создании объекта и т.д. отключил бы.

Но вы можете использовать ThreadPoolExecutor.getActiveCount(), чтобы получить представление о том, сколько потоков запущено в данный момент. Если он достигает 0 и остается там какое-то время, вы можете завершить работу исполнителя.

person Codebender    schedule 04.06.2015