CountdownLatch объединяет ожидание (maxTime) и обратный отсчет ()

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

Я использую обратный отсчет, чтобы остановить процесс, когда все потоки достигли максимального количества итераций. Другими словами, когда поток достигает максимального числа итераций, он уведомляет мой основной поток с помощью notifyThreadStop (), который, когда все потоки остановлены, запускает обратный отсчет ().

Примечание: мои потоки выполняются внутри FixedThreadPool ExecutorService.

Я хочу добавить защелку maxTime. Итак, я сделал следующее

List<Runnable> r = .... //(contains all my runnables)
myExecutorService.invokeAll(r);

if(maxtime > 0){
    mylatch.await(maxTime,TimeUnit.Seconds);
    (1)
    do stuff...
    exit;
}
else{
    mylatch.await();
    myExecutorService.shutdownNow();
    do stuff...
    exit;
}

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

Это не тот случай, когда достигнуто максимальное время. Итак, в (1) я хотел бы перебрать всех моих бегунов, чтобы завершить их цивилизованным способом :-). Для этого я определил функцию requestTermination (), которая, проще говоря, устанавливает для параметра iterationCounter значение MaxIterationCount в моих исполняемых файлах.

Итак, (1) станет

    for(Runnable runner: r){
        if(r.getIsRunning()){r.requestTermination();}
    }
    (2)

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

Итак, (2) станет

    mylatch2.await();
    myExecutorService.shutdownNow();

Конечно, мою функцию notifyThreadStop () нужно будет изменить, и для нее потребуется флаг, указывающий на выполнение обратного отсчета () на mylatch2, а не на mylatch.

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

Теперь возникает вопрос: есть ли лучший способ справиться с этим? Будет ли shutdownNow () в (1) или (2) единственным, что требуется? Зная, что мои потоки должны закрыть свой собственный файл журнала и закрыть свой внутренний вызываемый поток * ss * перед выходом.


person Bastan    schedule 04.02.2011    source источник


Ответы (2)


Если вы используете shutdownNow () и awaitTernimation (), это прервет все запущенные задачи и дождется их завершения.

При условии, что задачи могут быть прерваны и при прерывании правильно закрыть все ресурсы, проблем быть не должно. (Если есть проблема, это ошибка в коде вашей задачи, которую вы должны исправить)

person Peter Lawrey    schedule 04.02.2011
comment
Хорошо, я просмотрел http://www.ibm.com/developerworks/java/library/j-jtp05236.html, и я думаю, что понял. По сути, я заново изобретал колесо с помощью моего метода requestTermination (). Я сохраню это как ручной способ закрыть свою ветку. Он по-прежнему нужен в другой части моего кода. - person Bastan; 04.02.2011

Думаю, я только что ответил на свой вопрос, но поскольку все это было написано

Вы действительно это сделали :-) Если есть что добавить, так это то, что вы должны быть осторожны с RuntimeExceptions, иначе ваш shutdownNow () может никогда не быть вызван. Но вы это уже знали, верно?

person jpkrohling    schedule 04.02.2011