проблема с остановкой работающего потока с использованием volatile или atomic boolean

1

Я пытался остановить текущий поток, используя переменную volatile или атомную переменную. Но у меня есть некоторые сомнения в этом. Ниже приведен код, который я попробовал.

public class DemoThread {
class DemoRunnable implements Runnable {

    private String name;

    public volatile boolean isRunning = true;

    public DemoRunnable() {
    }

    public DemoRunnable(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public synchronized boolean isRunning() {
        return isRunning;
    }

    public synchronized void setRunning(boolean isRunning) {
        this.isRunning = isRunning;
    }

    @Override
    public void run() {

        System.out.println(" runnable ..." + name + " isRunning "
                + isRunning);

        while (isRunning) {
            int i;
            for (i = 0; i < 100; i++) {
                System.out.println("--------------------> i " + i
                        + " name " + name + " isRunning " + isRunning);
            }
            // if (i > 0) {
            // System.out.println(" volatile not working ");
            // throw new RuntimeException("volatile not working " + name);
            // }
        }
        System.out.println(" run method ends ..." + isRunning);
    }

}

private void demoStop(int count) {
    DemoRunnable runnable1 = new DemoRunnable("" + count);

    Thread t1 = new Thread(runnable1);
    Thread t2 = new Thread(runnable1);

    t1.start();
    t2.start();

    runnable1.isRunning = false;
    // runnable1.setRunning(false);

}

public static void main(String[] args) {
    DemoThread demoThread = new DemoThread();

    for (int i = 0; i < 200; i++) {
        try {
            demoThread.demoStop(i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

}

Увы, выполняя вышеприведенный код, иногда запускается метод run, содержащий цикл while. Каким образом остановить цикл while от запуска, как только isStopped установлено в значение false?

метод прерывания потока не остановит выполняемый метод.

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

  • 1
    Ваш код на самом деле работает. Вы запускаете t1.start() и цикл может выполняться несколько раз, прежде чем runnable1.isRunning = false; устанавливается в основной теме. Что ты хочешь делать?
  • 0
    isRunning() и setRunning() не нужно synchronized поскольку флаг isRunning является энергозависимым.
Показать ещё 2 комментария
Теги:
multithreading

1 ответ

1

Если ваши проверенные проверки являютсяInterrupted, прерывание() остановится там, как предполагалось.

    @Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        someTask();
        // thread can sleep if you like, add this block  
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            log.warn("Interrupted", e);
            break;
        }
    }
}

Ваш вложенный цикл НЕ проверяет атомный булев и, естественно, не остановится. Во всяком случае, interrupt() намного лучше, чем lame boolean flag. Дополнительную информацию см. В ExecutorService and Future.

  • 0
    Прерывание не остановит запущенный поток. Если поток переходит в режим ожидания или ожидания, генерируется только прерванное исключение. Исполнитель службы я не проверял, я проверю и опубликую.
  • 0
    Конечно не будет. Но цикл в приведенном выше примере будет. Я имел в виду, что этот код будет вести себя так же, как и вы, запустите его в службе исполнителя и затем вызовите отмену для объекта Future.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню