1. Введение
В этой краткой статье Мы покроем остановку Нить на Java – что не так просто со времен Thread.stop () метод депрекации.
Как поясняется в это обновление от Oracle, стоп () может привести к повреждению контролируемых объектов.
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 } } }
Вместо того, чтобы в то цикл оценки постоянной истинное , мы используем АтомныйБулеан и теперь мы можем начать/остановить исполнение, установив его правда/ложь.
Как поясняется в нашем введение в атомные переменные , использование АтомныйБулеан предотвращает конфликты при настройке и проверке переменной из разных потоков.
3. Прерывание потока
Что происходит, когда сон () установлен с длинным интервалом, или если мы ждем блокировка которые никогда не могут быть освобождены?
Мы сталкиваемся с риском блокирования в течение длительного периода или никогда не прекращается чисто.
Мы можем создать прерывать () для этих ситуаций давайте добавим несколько методов и новый флаг в класс:
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); } }
Мы добавили прерывать () метод, который устанавливает наши бег флаг к ложному и вызывает сигналы рабочего прерывать () метод.
Если поток спит, когда это называется, сон () выйдет с Прерванноеисключие, как и любой другой блокирующий вызов.
Это возвращает поток в цикл, и он выйдет с бег является ложным.
4. Заключение
В этом быстром учебнике мы рассмотрели, как использовать атомную переменную, необязательно в сочетании с призывом к прерывать (), для чистого выключаемого потока. Это, безусловно, предпочтительнее, чем называть стоп () метод и риск блокировки навсегда и повреждения памяти.
Как всегда, полный исходный код доступен более на GitHub .