1

Я хочу запланировать команду, которая будет выполняться через каждые 1 секунду. Команда будет увеличивать счетчик, и когда счетчик достигнет определенного предела, выполнение будет остановлено, и ExecutorService отключится. Поэтому я написал следующий фрагмент кода:Почему ScheduledExecutorService не может быть закрыт из самой Runnable?

import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.ScheduledFuture; 
import java.util.concurrent.TimeUnit; 
import java.util.concurrent.atomic.AtomicInteger; 

public class SchedulerTest { 

    private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 
    private ScheduledFuture<?> scheduledTask; 

    private AtomicInteger counter = new AtomicInteger(0); 

    public SchedulerTest() { 

    } 

    private void check() { 
     Runnable task = new Runnable() { 

      @Override 
      public void run() { 
       int currentValue = counter.incrementAndGet();     
       System.out.println(currentValue); 

       if(currentValue == 5) { 
        scheduledTask.cancel(false); 

        scheduler.shutdown(); 
        while(!scheduler.isTerminated()) {} 
       } 
      } 
     }; 

     scheduledTask = scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);         
    } 

    public static void main(String[] args) { 
     new SchedulerTest().check(); 
    } 
} 

Приведенный выше код предназначен исключительно для демонстрации целей.

Теперь я могу видеть следующее в моей консоли Eclipse:

console image

Красная кнопка в правом верхнем углу, показывает, что виртуальная машина все еще работает, как ExecutorService работает. Я разместил журнал внутри while, и я видел, что цикл никогда не прерывается.

Хотелось бы узнать, в чем причина такого поведения? Есть ли способ прервать ExecutorService из самой команды Runnable?

Я использую JDK6.

+2

'while (! Scheduler.isTerminated()) {}' избавиться от этой строки ... Spoiler: он поддерживает поток, который удерживает планировщик от завершения, который сохраняет условие false ... – Fildor

+0

'System.exit (-1); '... – Rhain

+0

Интересно, я выполнил код и обнаружил, что поток завершен после удаления цикла while. 'isShutdown' также может работать нормально. – tsuda7

ответ

2

Внутри метода выполнения вы проверки на состояние прекращения действия ThreadPool:

while(!scheduler.isTerminated()) {} 

Это будет сделать следующее:

  • Нить выполнения, что работоспособной войдет в цикл.
  • Поскольку поток по-прежнему «активен», то есть не закончил run, условие будет истинным («не завершено = истинно»).
  • Это будет поддерживать нить в петле навсегда.

Так что удалите это «while», и threadpool будет прекращен, как ожидалось.

P.S .: Если вы хотите дождаться завершения основной строки выполнения для пула, вы можете использовать awaitTermination.

+0

большое спасибо вам :) –

+0

Добро пожаловать :) – Fildor