ScheduledExecutorService: когда следует вызывать завершение работы?

Я использую ScheduledExecutorService в своем приложении. Мне нужно время от времени использовать его в определенном классе Utility для запуска запланированных потоков.

Хорошо ли хранить ScheduledExecutorService в статическом поле? Нужно ли в таком случае вызывать ScheduledExecutorService.shutdown()? Каков риск, если я не вызову завершение работы?

Вот что я думал сделать:

private static ScheduledExecutorService exec = Executors.newScheduledThreadPool(5);

public void scheduleTask(String name) {
        Future<?> future = futuresMapping.get(name);
        if(future!=null && !future.isDone())
            future.cancel(true);

        //execute once   
        Future<?> f = scheduledExecutor.schedule(new MyTask()), 1, TimeUnit.MINUTES);
        futuresMapping.put(name, f);
}

Спасибо


person lili    schedule 29.03.2012    source источник


Ответы (2)


Вы всегда должны вызывать shutdown() или shutdownNow(). Если вы этого не сделаете, ваше приложение может никогда не завершиться, поскольку все еще есть активные потоки (в зависимости от того, как вы завершаете свое приложение, находится ли оно в управляемой среде или нет и т. д.).

Обычно вы должны вызывать shutdown() из какого-либо метода события жизненного цикла, например из Spring DisposableBean.destroy(), или, если вы не используете какой-либо фреймворк, просто вызовите его перед выходом из вашего приложения.

person maximdim    schedule 29.03.2012
comment
Я попытался добавить scheduleExecutor.shutdownNow(); в моем ServletContextListener, но я получаю сообщение об ошибке в журнале tomcat, говорящее, что веб-приложение [/servlet], похоже, запустило поток с именем [Timer-0], но не смогло его остановить. Очень вероятно, что это приведет к утечке памяти. Как избежать этой ошибки? Спасибо за помощь - person lili; 29.03.2012
comment
shutdownNow() - это неблокирующий вызов, который будет немедленно возвращен. Вы должны вызывать awaitTermination() после того, что будет блокироваться до тех пор, пока пул потоков не будет фактически отключен. - person maximdim; 29.03.2012
comment
Я пробовал, не получилось. Должен ли я ждать дольше 30 секунд? Я написал более подробную информацию в stackoverflow.com/questions/9930624/ спасибо - person lili; 29.03.2012

Эффективная Java 2nd Ed говорит:

А вот как сказать исполнителю завершить работу корректно (если вы этого не сделаете, вполне вероятно, что ваша виртуальная машина не завершится):

executor.shutdown();

person Adrian    schedule 29.03.2012