Не понимая ключевое слово 'volatile'

1

Это класс потоков.

public class Processor extends Thread {

    public  boolean running = true;
    public void run()
    {
        while (running)
        {
            System.out.println("Hello from " + Thread.currentThread().getName());

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Это основной класс invoker

public class ProcessorInvoker {

    public static void main(String[] args) {

        Processor proc1= new Processor();
        proc1.start(); // ---->assuming thread0
        Processor proc2=new Processor();
        proc2.start(); // ---->assuming thread1

        proc1.running=false;
    }
}

Насколько я понимаю ключевое слово volatile: когда логическая переменная в классе Processor не является VOLATILE, значение этой переменной, измененное на "false", не повлияет на thread1, потому что измененное значение false--> proc1.running = false не является видимый thread1, поэтому thread1 продолжает работать, но thread0 останавливается.

Когда логическая переменная сделана VOLATILE, я понял, так как я изменил значение переменной boolean на false, тогда thread1 также видит это изменение и останавливается, но это не происходит на выходе. Я вижу тот же вывод, thread0 останавливается, но thread1 все еще работает. Я думал, что оба потока должны остановиться. Может кто-нибудь, пожалуйста, прояснить это? Скажите, пожалуйста, где я ошибаюсь.

  • 2
    Просто чтобы прояснить это: если вы не используете ключевое слово volatile, оно все равно может работать (и на самом деле оно часто работает, поэтому многие люди не пишут правильный код, потому что не учатся на боли). На самом деле это может работать в некоторых случаях (некоторые версии JVM, некоторые платформы и некоторые условия в зависимости от количества повторений и размера кода), но не в других. Поэтому всегда программируйте его правильно, даже когда ваши тесты пройдены.
Теги:
multithreading
volatile

1 ответ

7

У вас есть два экземпляра Processor, поэтому, когда вы делаете proc1.running=false; вы останавливаете только один из потоков. Вам нужно вызвать proc2.running=false; а также остановить proc2.

Каждый из ваших объектов резьбы имеет свои собственные версии переменного экземпляра running. Вы могли бы сделать эту переменным статическими, а затем как бы перестает работать (при условии, что потоки выполняются и ударили состояние времени, прежде чем какой -либо другой код, возможно, изменения running обратно к истине).

Я думал, что обе нити должны остановиться

Когда ваши источники сообщают, что другие потоки должны видеть последнее значение изменчивой переменной, это не означает, что другие потоки (как и в объектах Thread), у которых есть эквивалентная версия переменной, изменились. Они означают, что когда другие потоки выполнения пытаются получить доступ к этой переменной (будь то в объекте Thread или любом другом виде объекта), они будут видеть последнее значение.

Ещё вопросы

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