Я хочу немедленно остановить Java-поток, но когда я пытаюсь выполнить поток, требуется некоторое время перед остановкой. Есть ли способ принудительно остановить поток Java?
Есть ли хороший способ принудительно остановить поток Java?
Ответ 1
Нет хорошего способа остановить поток мгновенно.
Существует
Thread.stop()
, но это опасно, устарело и удалено в Java 11. Не используйте его, если:Вы полностью понимаете проблемы,
Вы тщательно проанализировали свой код и определили, что проблемы не применимы и/или риски приемлемы, и
вам все равно, что ваше приложение застрянет на Java 8 или более ранней версии.
Существует
Thread.interrupt()
, но нет никакой гарантии, что нить остановится быстро или вообще остановится. Поведение будет зависеть от того, был ли разработан код потока приложения, чтобы замечать и правильно реагировать на прерывания.Существует подход к написанию потока для периодической проверки флага, но если флаг проверяется не часто (случайно или намеренно), то поток не остановится быстро.
FWIW, флаг и подходы interrupt()
во многом совпадают. В обоих случаях поток, который ожидает прерывания, должен регулярно проверяться; например позвонив в interrupted()
или isInterrupted()
или проверив флаг.
Разница между подходами заключается в том, что механизм interrupt()
будет работать, когда код ожидает notify()
или заблокирован в операции ввода-вывода. Из-за этого и потому, что interrupt
является приемлемым независимым от приложения способом сделать это, он обычно предпочтительнее механизма flag
для конкретного приложения.
Ответ 2
Существует один хороший способ безопасно (и быстро) принудительно остановить поток:
System.exit(0)
К сожалению, у этого есть побочный эффект, убивающий все остальные потоки.
Ответ 3
Запуск Thread не может быть остановлен с помощью Thread.Interrupt
, только остановки или блокировки потоков можно остановить с помощью Thread.Interrupt
. Но используя общую переменную, чтобы сигнализировать, что она должна остановить то, что она делает. Поток должен периодически проверять переменную (например: использовать цикл while) и выходить упорядоченным образом.
private boolean isExit= false;
public void beforeExit() {
isExit= true;
}
public void run() {
while (!isExit) {
}
}
Ответ 4
Ни при каких обстоятельствах не используйте Thread.stop - если вы задаете этот вопрос, вы недостаточно понимаете модель потоков Java, чтобы безопасно ее использовать.
Подробности, для любопытных, здесь: Java Thread Primitive Deprecation
Если вы хорошо разбираетесь в параллелизме Java, то поймете, почему вы никогда не должны его использовать, и что даже если он полностью безопасен в вашем собственном коде, он делает ваш код зараженным и непригодным для использования кем-либо еще. Вместо этого вы, вероятно, в конечном итоге будете использовать трюк с булевыми переменными или какой-либо другой шаблон, чтобы сообщить потоку, когда он должен завершиться, а затем выйти.
Не используйте Thread.stop. Когда-либо.
Ответ 5
Ваш поток может быть помещен в цикл while и каждый раз проверять логическую переменную. Когда вы установите переменную в значение false, цикл закончится, и поток также закончится. Чтобы завершить поток перед прохождением текущего цикла, вы можете использовать ключевое слово break.
Это позволяет избежать использования устаревших методов, таких как Thread.stop().
private boolean run = true;
//Call this method to end your thread
void stopRunning(){
run = false;
}
//This loop would go into the overided run() method
while(run){
//Put your task here
}
Поток завершит текущую задачу и затем остановится сам.
Если вам нужно остановить поток перед завершением задачи, вы можете проверить переменную run, используя if/else где-нибудь в цикле, и завершить поток так же, как и где-либо еще.
while(run){
//Your code here
/*Be sure your not stopping the task at a point that will harm your program.*/
if(!run){break;}
}