Как вы убиваете Thread в Java?

Как вы убиваете java.lang.Thread в Java?

14 Solutions collect form web for “Как вы убиваете Thread в Java?”

См. Эту тему от Sun, почему они устарели Thread.stop() . Он подробно рассказывает о том, почему это плохой метод, и что нужно сделать, чтобы безопасно остановить streamи в целом.

То, как они рекомендуют, – использовать общую переменную в качестве флага, который просит остановить фоновый stream. Затем эту переменную можно установить другим объектом, запрашивающим завершение streamа.

Как правило, вы не ..

Вы просите его прервать все, что он делает, используя Thread.interrupt () (ссылка javadoc)

Хорошее объяснение, почему в javadoc здесь (ссылка java technote)

В Java нити не убиты, но остановка streamа выполняется в совместном режиме . Поток просят закончить, и stream может затем законно завершить работу.

Часто используется поле volatile boolean field, которое stream периодически проверяет и завершает, когда он установлен на соответствующее значение.

Я бы не использовал boolean чтобы проверить, должен ли stream заканчиваться . Если вы используете volatile в качестве модификатора поля, это будет работать надежно, но если ваш код станет более сложным, вместо использования других методов блокировки внутри цикла while может случиться так, что ваш код вообще не завершится или, по крайней мере, займет больше времени как вы могли бы захотеть.

Некоторые методы блокировки библиотеки поддерживают прерывание.

Каждый stream уже имеет состояние булевского флага, и вы должны его использовать. Он может быть реализован следующим образом:

 public void run() { try { while (!interrupted()) { // ... } } catch (InterruptedException consumed) /* Allow thread to exit */ } } public void cancel() { interrupt(); } 

Исходный код, адаптированный из Java Concurrency на практике . Поскольку метод cancel() является общедоступным, вы можете позволить другому streamу вызывать этот метод по своему усмотрению.

Один из способов – установить переменную classа и использовать ее в качестве часового.

 Class Outer { public static volatile flag = true; Outer() { new Test().start(); } class Test extends Thread { public void run() { while (Outer.flag) { //do stuff here } } } } 

Задайте внешнюю переменную classа, то есть флаг = true в приведенном выше примере. Установите для него значение false, чтобы «убить» stream.

Есть способ, как вы можете это сделать. Но если вам пришлось использовать его, либо вы плохой программист, либо используете код, написанный плохими программистами. Итак, вы должны подумать о том, чтобы перестать быть плохим программистом или прекратить использование этого плохого кода. Это решение предназначено только для ситуаций, когда нет другого пути.

 Thread f =  Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} ); m.setAccessible( true ); m.invoke( f , new ThreadDeath() ); 

Я хочу добавить несколько замечаний, основываясь на накопленных комментариях.

  1. Thread.stop () остановит stream, если это разрешит менеджер безопасности.
  2. Thread.stop () опасен. Сказав это, если вы работаете в среде JEE, и у вас нет контроля над вызываемым кодом, это может быть необходимо.
  3. Вы никогда не должны останавливать stream рабочего контейнера. Если вы хотите запустить код, который имеет тенденцию зависать, (осторожно) запустить новый stream демона и контролировать его, при необходимости убивая.
  4. stop () создает новую ThreadDeath-ошибку в вызывающем streamе, а затем приводит к тому, что Ошибка применяется к целевому streamу. Поэтому трассировка стека обычно бесполезна.
  5. В JRE 6 stop () проверяет с помощью менеджера безопасности, а затем вызывает stop1 (), который вызывает stop0 (). stop0 () – это собственный код.

Я проголосовал за Thread.stop() .

Например, у вас есть длительная операция (например, сетевой запрос). Предположительно вы ожидаете ответа, но это может занять время, и пользователь перешел к другому пользовательскому интерфейсу. Этот ожидающий stream теперь a) бесполезен b) потенциальная проблема, потому что, когда он получит результат, он совершенно бесполезен, и он вызовет обратные вызовы, которые могут привести к количеству ошибок.

Все это и он может выполнять обработку ответа, которая может быть интенсивной. И вы, как разработчик, не можете даже остановить его, потому что вы не можете выбросить, if (Thread.currentThread().isInterrupted()) строки во всем коде.

Таким образом, неспособность принудительно остановить stream это странно.

Вопрос довольно расплывчатый. Если вы имели в виду «как мне написать программу, чтобы stream прекратил работу, когда я захочу», тогда вам будут полезны различные другие ответы. Но если вы имели в виду «У меня есть чрезвычайная ситуация с сервером, я не могу перезапустить прямо сейчас, и мне просто нужен конкретный stream, чтобы умереть, идите, что может», тогда вам понадобится инструмент вмешательства, чтобы сопоставить инструменты мониторинга, такие как jstack .

Для этого я создал jkillthread . Ознакомьтесь с инструкциями по использованию.

Конечно, есть случай, когда вы используете какой-то не полностью доверенный код. (У меня лично есть это, позволяя загружать сценарии для выполнения в моей среде Java. Да, повсеместно звучит звонок тревоги, но это часть приложения.) В этом неудачном случае вы в первую очередь просто надеетесь, попросив сценаристов для соблюдения какого-то булевского сигнала запуска / отсутствия сигнала. Единственным достойным отказом является вызов метода stop в streamе, если, скажем, он работает дольше, чем некоторый тайм-аут.

Но это просто «порядочный», а не абсолютный, потому что код может поймать ошибку ThreadDeath (или любое исключение, которое вы явно бросаете), а не ретронировать его, как должен вести себя джентльменский stream. Таким образом, в нижней строке AFAIA нет абсолютного отказа безопасности.

Невозможно изящно убить нить.

Вы можете попытаться прервать stream, одна общая страtagsя состоит в том, чтобы использовать ядовитую таблетку для сообщения о streamе, чтобы остановить себя

 public class CancelSupport { public static class CommandExecutor implements Runnable { private BlockingQueue queue; public static final String POISON_PILL = “stopnow”; public CommandExecutor(BlockingQueue queue) { this.queue=queue; } @Override public void run() { boolean stop=false; while(!stop) { try { String command=queue.take(); if(POISON_PILL.equals(command)) { stop=true; } else { // do command System.out.println(command); } } catch (InterruptedException e) { stop=true; } } System.out.println(“Stopping execution”); } } 

}

 BlockingQueue queue=new LinkedBlockingQueue(); Thread t=new Thread(new CommandExecutor(queue)); queue.put(“hello”); queue.put(“world”); t.start(); Thread.sleep(1000); queue.put(“stopnow”); 

http://anandsekar.github.io/cancel-support-for-threads/

Как правило, вы не убиваете, не останавливаете или не прерываете нить (или проверяете, прерывается ли она ()), но пусть это прекратится естественным образом.

Это просто. Вы можете использовать любой цикл вместе с (volatile) логической переменной внутри метода run () для управления деятельностью streamа. Вы также можете вернуться из активного streamа в основной stream, чтобы остановить его.

Таким образом вы грациозно убиваете нить :).

Попытки резкого прекращения streamа являются хорошо известной плохой практикой программирования и доказательством плохого дизайна приложения. Все streamи в многопоточном приложении явно и неявно используют одно и то же состояние процесса и вынуждены сотрудничать друг с другом, чтобы поддерживать его согласованность, иначе ваше приложение будет подвержено ошибкам, которые очень трудно диагностировать. Таким образом, разработчик несет ответственность за обеспечение такой согласованности посредством тщательного и четкого проектирования приложений.

Существует два основных правильных решения для контролируемых streamов:

  • Использование общего флагового флага
  • Использование пары методов Thread.interrupt () и Thread.interrupted ().

Хорошее и подробное объяснение проблем, связанных с прерывистым завершением streamов, а также примеры неправильных и правильных решений для контролируемого прекращения streamов можно найти здесь:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

Вот несколько хороших чтений по теме:

Что вы делаете с InterruptedException?

Автоматическое закрытие streamов

Я не получил прерывание для работы на Android, поэтому я использовал этот метод, отлично работает:

 boolean shouldCheckUpdates = true; private void startupCheckForUpdatesEveryFewSeconds() { Thread t = new Thread(new CheckUpdates()); t.start(); } private class CheckUpdates implements Runnable{ public void run() { while (shouldCheckUpdates){ //Thread sleep 3 seconds System.out.println("Do your thing here"); } } } public void stop(){ shouldCheckUpdates = false; } 
Interesting Posts

Панель задач Windows 10 и меню «Пуск» не загружаются

Какие вещи можно безопасно удалить или удалить из новой установки Windows 7?

Можно ли выполнить файл после извлечения из архива самораспаковывающегося архива 7-Zip (SFX)?

Как остановить открытие каждого файла пакета как процесс с именем cmd.exe, как показано в диспетчере задач

Как настроить брандмауэр Windows 7 на запрос исходящего трафика?

Сценарий установки для нескольких программных пакетов

Кнопка добавления / вычитания Excel VBA

Как заставить Microsoft Search индексировать общие типы файлов, например .pdf и .pub

Windows: как я могу перенаправить звук, поступающий от микрофона к выходу динамиков

Как определить текущий номер версии приложения с помощью apt-get

Как автоматически запускать приложение в качестве администратора и делать его пользовательский интерфейс видимым для пользователей, не являющихся администраторами, под Windows 8

Настройка экспортного шаблона org-mode?

Как найти и заменить пути ссылок в нескольких файлах Excel одновременно

Linux NetworkManager не может подключиться

Что делает «Оптимизация дисков» в Windows 8?

Давайте будем гением компьютера.