Как да убиете Java нишка

1. Въведение

В тази кратка статия ще разгледаме спирането на нишка в Java - което не е толкова просто, тъй като методът Thread.stop () е остарял.

Както е обяснено в тази актуализация от Oracle, stop () може да доведе до повредени наблюдавани обекти.

2. Използване на флаг

Нека започнем с клас, който създава и стартира нишка. Тази задача няма да завърши сама, затова се нуждаем от някакъв начин да спрем тази нишка.

За това ще използваме атомен флаг:

public class ControlSubThread implements Runnable { private Thread worker; private final AtomicBoolean running = new AtomicBoolean(false); private int interval; public ControlSubThread(int sleepInterval) { interval = sleepInterval; } public void start() { worker = new Thread(this); worker.start(); } public void stop() { running.set(false); } public void run() { running.set(true); while (running.get()) { try { Thread.sleep(interval); } catch (InterruptedException e){ Thread.currentThread().interrupt(); System.out.println( "Thread was interrupted, Failed to complete operation"); } // do something here } } }

Вместо да имаме цикъл while, който оценява константата true , ние използваме AtomicBoolean и сега можем да започнем / спрем изпълнението, като го зададем на true / false.

Както е обяснено в нашето въведение към атомните променливи, използването на AtomicBoolean предотвратява конфликти при настройката и проверката на променливата от различни нишки.

3. Прекъсване на нишка

Какво се случва, когато режимът sleep () е зададен на дълъг интервал или ако чакаме заключване, което може никога да не бъде освободено?

Изправени сме пред риска да блокираме за дълъг период или никога да не прекратим чисто.

Можем да създадем прекъсването () за тези ситуации, нека добавим няколко метода и нов флаг към класа:

public class ControlSubThread implements Runnable { private Thread worker; private AtomicBoolean running = new AtomicBoolean(false); private int interval; // ... public void interrupt() { running.set(false); worker.interrupt(); } boolean isRunning() { return running.get(); } boolean isStopped() { return stopped.get(); } public void run() { running.set(true); stopped.set(false); while (running.get()) { try { Thread.sleep(interval); } catch (InterruptedException e){ Thread.currentThread().interrupt(); System.out.println( "Thread was interrupted, Failed to complete operation"); } // do something } stopped.set(true); } } 

Добавихме метод interrupt () , който задава текущия ни флаг на false и извиква метода interrupt () на работната нишка .

Ако нишката спи, когато това се извика, sleep () ще излезе с InterruptException, както и всяко друго блокиращо повикване.

Това връща нишката в цикъла и тя ще излезе, тъй като стартирането е false.

4. Заключение

В този бърз урок разгледахме как да използваме атомна променлива, по избор комбинирана с повикване за прекъсване (), за чисто изключване на нишка. Това определено е за предпочитане пред извикването на остарелия метод stop () и рискът да се заключи завинаги и да се повреди паметта.

Както винаги, пълният изходен код е достъпен в GitHub.