CountdownLatch объединяет ожидание (maxTime) и обратный отсчет () - PullRequest
1 голос
/ 04 февраля 2011

У меня есть несколько потоков, работающих почти бесконечное время и количество итераций.Счетчик итераций сбрасывается до 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 в моих runnables.

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

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

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

Так (2) станет

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 04 февраля 2011

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

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

0 голосов
/ 04 февраля 2011

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

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

...