0

У меня есть Java ExecutorService (Fixed Thread Pool из 1), в который я передаю выполняемые задачи для будущего выполнения. Каждая задача обычно завершается в течение 10 секунд. Служба ExecutorService просто выполняет свои задачи. Если я выключу свое приложение, я запустил следующее:Java ExecutorService ShutdownNow принимает меры

if (taskProcessor != null) { 
    taskProcessor.shutdownNow(); 
    while (!taskProcessor.isTerminated()) { 
     // Wait For All Submitted Tasks To Finish 
    } 
} 

Проблема заключается в том, что, кажется, занимает возраст для него для завершения работы, иногда это может занять несколько минут, иногда кажется, никогда не отключается и иногда отключений в считанные секунды! В любой момент в очереди исполнителей потенциально может быть около 2000 задач, но я просто хочу, чтобы она завершила выполнение текущей задачи и прекратила работу. Что я здесь делаю неправильно?

+0

Занятое ожидание редко является хорошей идеей. – Raedwald

ответ

0

Все зависит от выполняемых задач. ThreadPoolExecutor не закончится до завершения всех задач. shutdownNow() прерывает все задачи, но задачи могут игнорировать его.

+0

Спасибо, я добавлю некоторые отладки и попытаюсь изучить, если это то, что происходит. У меня есть таймер, прикрепленный к каждой задаче, чтобы отслеживать таймауты задачи, поэтому задаваясь вопросом, не является ли это проблемой, и запущенная задача игнорирует прерывание из-за таймера. – Ashley

+0

Обратите внимание, что задача может реагировать только на прерывания, если она предназначена для этого –

+0

. Думаю, это проблема. Я просто добавляю catch InterruptedException и обертываю задачу циклом while. Надеюсь, моя отладка мгновенно прольет некоторый свет. – Ashley

0

Вы не следовали правильной последовательности до выключения ExecutorService.

Вы должны вызвать shutdown, shutdownNow и awaitTermination в определенном порядке в соответствии с рекомендациями oracle

void shutdownAndAwaitTermination(ExecutorService pool) { 
    pool.shutdown(); // Disable new tasks from being submitted 
    try { 
    // Wait a while for existing tasks to terminate 
    if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { 
     pool.shutdownNow(); // Cancel currently executing tasks 
     // Wait a while for tasks to respond to being cancelled 
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) 
      System.err.println("Pool did not terminate"); 
    } 
    } catch (InterruptedException ie) { 
    // (Re-)Cancel if current thread also interrupted 
    pool.shutdownNow(); 
    // Preserve interrupt status 
    Thread.currentThread().interrupt(); 
    } 
} 
0

Вы можете сделать лучше, не имея кода делает занят ожидание. Это освободит процессор, чтобы завершить выполнение задач. И предотвратите конкуренцию для любого замка, используемого isTerminated.

Смежные вопросы