由于删除了局部变量,Java volatile关键字行为会发生变化

时间:2017-03-18 11:23:49

标签: java volatile

link开始,它提供了java关键字' volatile'的演示。演示代码工作正常。但我尝试做一点修改。这种行为是不同的。

我的代码:

public class VolatileTest4 {

    private static int MY_INT = 0;

    public static void main(String[] args) {
        new ChangeListener().start();
        new ChangeMaker().start();
    }

    static class ChangeListener extends Thread {
        @Override
        public void run() {
            while (MY_INT < 5) {
                System.out.println("Got Change for MY_INT : " + MY_INT);
            }
        }
    }

    static class ChangeMaker extends Thread {
        @Override
        public void run() {

            while (MY_INT < 5) {
                System.out.println("Incrementing MY_INT to " + MY_INT);
                MY_INT++;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

我所做的只是删除local_value的局部变量。 帖子说&#39;没有volatile关键字,更改监听器循环无限循环#39; 但我的代码是没有volatile关键字,更改侦听器正常结束。

什么是干扰?是什么导致改变听众结束?

1 个答案:

答案 0 :(得分:1)

我已经将您提供的代码与文章中的代码进行了比较,并且存在实质性差异。以作者描述的方式修改并运行文章中的代码后,我能够复制他的结果。我的代码如下:

public class VolatileTest {

    private static int MY_INT = 0;

    public static void main(String[] args) {
        new ChangeListener().start();
        new ChangeMaker().start();
    }

    static class ChangeListener extends Thread {
        @Override
        public void run() {
            int local_value = MY_INT;
            while ( local_value < 5){
                if( local_value!= MY_INT){
                    System.out.println(String.format("Got Change for MY_INT : %S", MY_INT));
                    local_value= MY_INT;
                }
            }
        }
    }

    static class ChangeMaker extends Thread{
        @Override
        public void run() {

            int local_value = MY_INT;
            while (MY_INT <5){
                System.out.println(String.format("Incrementing MY_INT to %S", local_value+1));
                MY_INT = ++local_value;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }
}

volatile关键字更改了变量的可见性语义。在写入操作完成后,对标记为volatile的成员的更改将对所有线程可见。 但是,缺少volatile 并不意味着赢得的更改可见。 volatile提供了一些关于可见性的确定性;没有它,您无法确定何时对其他线程中的值所做的更改是否可见。

作者试图指出,由于变量未标记为volatileChangeMaker所做的更改对ChangeReader不可见,反过来ChangeListener volatile 1}}永远不会终止。有关scalerY = StandardScaler().fit(trainY) # fit y scaler pipeline.fit(trainX, scalerY.transform(trainY)) # fit your pipeline to scaled Y testY = scalerY.inverse_transform(pipeline.predict(testX)) # predict and rescale 关键字的更好处理,请参阅this文章。