Остановка бесконечного цикла Runnable запустить из ThreadPool - PullRequest
2 голосов
/ 24 августа 2011

У меня есть Runnable реализующий класс, который будет запускаться с Executors.newFixedThreadPool Внутри Runnable у меня работает бесконечный цикл, который прослушивает UDP-порт для входящих данных.

Я хочу изящно завершить Runnable, чтобы закрыть указанные порты UDP.

Как мне этого добиться? При прямом расширении Thread у меня есть доступ к interrupt (), isInterupted () и т. Д., На которых я могу основать свой бесконечный цикл.

Однако в классе реализации Runnable я хочу сделать что-то вроде

@Override
public void run() {
    while (active) {

    }
}

и имеют

private boolean active = true;

Как установить active = false, когда ThreadPool завершен?

Ответы [ 4 ]

8 голосов
/ 24 августа 2011

Вы можете получить доступ к флагу прерывания текущего потока, используя статический метод Thread.interrupted(), например, вместо вашего флага active используйте:

public void run() {
    try {
        // open your ports
        while (!Thread.interrupted()) {
            // do stuff
        }
    } finally {
        // close your ports in finally-block
        // so they get closed even on exceptions
    }
}

И когда вы хотитечтобы отключить ExecutorService, позвоните на него shutdownNow().Это будет interrupt() любым работающим рабочим потоком, и ваш Runnable выйдет из его цикла.

2 голосов
/ 24 августа 2011

если вы получите Future при отправке задачи, вы можете cancel(boolean) будущее, если вы передадите true, поток, на котором выполняется задача, будет прерван

@Override
public void run() {
    try{
        while (!Thread.interrupted()) {


             if(Thread.interrupted())return;//to quit from the middle of the loop
        }
    }finally{
        //cleanup
    }
}

обратите внимание, что у вас будетсбросить флаг прерывания с помощью Thread.currentThread().interrupt(); каждый раз, когда выдается выброшенное исключение InterruptedException

1 голос
/ 24 августа 2011

Я бы предложил не использовать 'Runnable', а переопределить 'FutureTask' и реализовать методы 'done' и 'cancel' (при необходимости), где вы можете выполнить все необходимые операции очистки.

EDIT:

забыл метод отмены.

1 голос
/ 24 августа 2011

вы можете использовать это

while (!executor.isShutdown) {
//do your job
}

или использовать AtomicBoolean в цикле while.(предпочтительно более volatile)

Этот флаг можно установить, если вы хотите остановить обработку вручную, с помощью какого-либо метода, например stopProcessing()

...