Рубрики
Без рубрики

Как убить поток Java

Узнайте, как правильно остановить поток в Java.

Автор оригинала: baeldung.

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 .