Стандартная практика Java ScheduledExecutorService

Я использую ScheduledExecutorService в приложении J2EE для планирования задачи каждые x секунд, взятой из файла конфигурации (собирает данные из базы данных и отправляет их на внешний сервер). Мой код:

try{
    final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
    service.scheduleWithFixedDelay(new Runnable(){
    public void run(){
                RsaBaseAction rsa = RsaBaseAction.getInstance();//class that does all the work
                rsa.rsaBaseAction();
            }
          }, 0, timeInterval, TimeUnit.SECONDS);
     }
     catch(Exception ex){
         ex.printStackTrace();
     }

Мой вопрос: есть ли дополнительный код, который я должен написать? Должен ли я написать цикл while, чтобы убедиться, что поток завершен, а затем выполнить service.shutdown() или ScheduledExecutorService позаботится об этом за меня?


person full stackoverflow developer    schedule 12.05.2014    source источник


Ответы (2)


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

Пример. Вы пишете CMS, которая предлагает интеграцию с Google Shopping для загрузки информации о продукте. Если пользователь удалит информацию о загрузке (т. е. выключит ее), вы можете вызвать завершение работы, чтобы служба не выполняла синхронизацию.

person sksamuel    schedule 12.05.2014
comment
а понял, спасибо. Моя вещь должна работать бесконечно, пока сервер приложений не остановится. Я просто беспокоился об утечках памяти или постоянном появлении потоков. - person full stackoverflow developer; 12.05.2014
comment
Планировщик внутри имеет один поток для запуска вашего кода. Вот почему метод называется newSingleThreadScheduledExecutor. Если вы запланировали 10 000 исполняемых модулей, все они будут выполняться в одном потоке, хотя и медленно. - person sksamuel; 12.05.2014

Как четко указано в Javadoc по методу shutdown:

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

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

Что касается кода у вас - не вижу смысла в блоке try-catch. Планирование задач не создает никаких исключений. Похоже, вы хотите на самом деле попытаться поймать rsaBaseAction вместо планирования (если исключение выдается исполняемым, выполнение больше не планируется, и исключение обрабатывается обработчиком исключений группы потоков)

person Ordous    schedule 12.05.2014
comment
у меня не было try-catch, но кажется, что когда в задаче возникает исключение, в консоли нет печати трассировки стека, вместо этого она переходит в собственный код ScheduledExecutorService и там зависает. Мне потребовалось время, чтобы понять это, ха-ха. Я положил улов туда, чтобы увидеть, будет ли он пойман здесь вместо этого - person full stackoverflow developer; 12.05.2014