Есть ли хороший способ принудительно остановить поток Java?

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

Ответ 1

Нет хорошего способа остановить поток мгновенно.

  • Существует Thread.stop(), но это опасно, устарело и удалено в Java 11. Не используйте его, если:

    1. Вы полностью понимаете проблемы,

    2. Вы тщательно проанализировали свой код и определили, что проблемы не применимы и/или риски приемлемы, и

    3. вам все равно, что ваше приложение застрянет на 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;}
}