2016-09-09 2 views
0

У меня есть класс MyRunnable, который реализует интерфейс Runnable. Класс инстанциирован от основного потока, как это:Прерывание в Runnable прерывает другие потоки?

MyRunnable myRunnable = new MyRunnable(); 
Thread thread = new Thread(myRunnable); 
thread.start(); 

MyRunnable реализует stop() метод, который останавливает поток и также вызывает interrupt() на текущем потоке:

public void stop() 
{ 
    LOG.info("Stopping"); 
    this.runService = false; // reset running flag in order to stop the while-loop 
    Thread.currentThread().interrupt(); // interrupt any blocking operations 
} 

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

Я думал, что создание/запуск/остановка Runnable довольно просто, но, возможно, я что-то делаю неправильно?

+2

С какой темы вы вызываете метод 'stop()'? –

+0

От главного потока. –

+0

'interrupt()' прерывает один поток, который вы вызываете, а не только тот, который вы создали ранее. –

ответ

3

Вы, вероятно, звоните myRunnable.stop() из основного потока. Это приведет к тому, что Thread.currentThread().interrupt() просто прервет основную нить.

Вы не должны делать предположений о вызывающем потоке в этом методе. Если ваше намерение состоит в том, чтобы фактически прервать поток, созданный для выполнения вашей runnable, вам следует как-то передать эту ссылку thread на вашу реализацию Runnable и позвонить thread.interrupt() вместо того, чтобы возиться с currentThread().

+0

Спасибо, это звучит разумно. Если 'MyRunnable' расширяет' java.lang.Thread' вместо реализации интерфейса Runnable, вызов 'Thread.currentThread(). Interrupt()' также прерывает основной поток или действительно ** только ** текущий поток? Я скорее думаю об изменении класса вообще, потому что мне нужно поймать 'InterruptException' внутри. –

+0

@MarkusL Вам также нужно что-то, что проверяет флаг прерывания. Если вы не назовете такой метод, исключение InterruptedException не будет выбрано. –

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