Как поток должен закрываться в Java?
Это короткий вопрос. В какой-то момент моя нить понимает, что это должно быть самоубийство. Каков наилучший способ сделать это:
- Thread.currentThread() прерывания();.
- возвращение;
Кстати, почему в первом случае нам нужно использовать
currentThread
? Является ли
Thread
не ссылкой на текущий поток?
Ответы
Ответ 1
Если вы хотите прервать поток, то просто возврат будет прекрасным. Вам не нужно вызывать Thread.currentThread().interrupt()
(он не будет делать ничего плохого, но это вам просто не нужно.) Это связано с тем, что interrupt()
в основном используется для уведомления владельца потока (ну, а не 100 % точной, но вроде). Поскольку вы являетесь владельцем потока, и вы решили прекратить поток, никто не должен уведомлять, поэтому вам не нужно его вызывать.
Кстати, почему в первом случае мы нужно использовать currentThread? Это тема не относится к текущему потоку?
Да, это не так. Я думаю, это может сбивать с толку, потому что, например, Thread.sleep() влияет на текущий поток, но Thread.sleep() является статическим методом.
Если вы НЕ являетесь владельцем потока (например, если вы не расширили Thread
и закодировали Runnable
и т.д.), вы должны сделать
Thread.currentThread().interrupt();
return;
Таким образом, любой код, который вызвал ваш runnable, будет знать, что поток прерывается = (обычно) должен прекратить все, что он делает, и завершать. Как я сказал ранее, это всего лишь механизм коммуникации. Владелец может просто игнорировать прерванный статус и ничего не делать. Но если вы установите прерванный статус, кто-то может поблагодарить вас за это в будущем.
По этой же причине вы никогда не должны делать
Catch(InterruptedException ie){
//ignore
}
Потому что, если вы это сделаете, вы прекратите сообщение там. Вместо этого нужно делать
Catch(InterruptedException ie){
Thread.currentThread().interrupt();//preserve the message
return;//Stop doing whatever I am doing and terminate
}
Ответ 2
Если метод запуска завершен, поток завершится.
Если вы используете цикл, правильный способ выглядит следующим образом:
// In your imlemented Runnable class:
private volatile boolean running = true;
public void run()
{
while (running)
{
...
}
}
public void stopRunning()
{
running = false;
}
Конечно, возвращение - лучший способ.
Ответ 3
Если вы находитесь на верхнем уровне - или можете чисто добраться до верхнего уровня - потока, то просто возвращение - это хорошо. Выбрасывание исключения не так чисто, как вам нужно, чтобы убедиться, что ничего не поймать исключение и игнорировать его.
Причина, по которой вам нужно использовать Thread.currentThread()
для вызова interrupt()
, заключается в том, что interrupt()
- это метод экземпляра - вам нужно вызвать его в потоке, который вы хотите прервать, что в вашем случае является текущая нить. Обратите внимание, что прерывание будет замечено только в следующий раз, когда поток будет блокироваться (например, для ввода-вывода или для монитора) в любом случае - это не означает, что исключение будет немедленно отправлено.
Ответ 4
Если вы просто вызываете interrupt()
, поток не будет автоматически закрыт. Вместо этого Thread может даже продолжать жить, если isInterrupted()
реализовано соответствующим образом. Единственный способ гарантировать закрытие потока, по запросу OP, - это
Thread.currentThread().stop();
Метод устарел, однако.
Вызов return
возвращает только текущий метод. Это только завершает поток, если вы находитесь на его верхнем уровне.
Тем не менее, вы должны работать с interrupt()
и создавать свой код вокруг него.
Ответ 5
Thread - это класс, а не экземпляр; currentThread() - это статический метод, который возвращает экземпляр Thread, соответствующий вызывающему потоку.
Используйте (2). interrupt() является немного жестоким для нормального использования.