2

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

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

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

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

Решение в этом случае должно вызвать shutdown() в конце основного, но мое фактическое приложение сложнее. Внутри 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"); 
     } 
    }); 
} 

}

+1

Продолжайте читать до конца. Вы должны убедиться, что неиспользуемые нити умирают. –

ответ

5

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

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

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

-1

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

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