首页 » Java » java volatile 关键字

java volatile 关键字

原文 http://blog.csdn.net/kai1ge1/article/details/79163301

2018-01-25 17:39:44阅读(402)

volatile 关键字

volatile主要有两种作用,一个是保证其可见性,另一个则是保证其顺序性。
可见性:多个线程共享一个变量,每个线程都会将这个共享变量存放一份到自己的变量区,当一个线程修改了这个共享变量,它首先会修改到自己的变量区,可能并不会立即修改到公共的内存区。如果加上volatile这个修饰,则当值修改的时候,会立即同步到公共内存区,同时每个线程的变量区都将失效,重新获取公共内存区里面的值。

顺序性:在java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性,而volatile就确保了顺序不被打乱。

可见性的具体实例,用一个标志位来停止另一个线程的运行。具体代码如下:
public class Test {
    private volatile static boolean isStop = false;
    public static void main(String[] arg0){
        Thread thread = new Thread(new Test().new MyThread());
        thread.start();
        isStop = true;
    }
    class MyThread implements Runnable{
        @Override
        public void run() {
            while (!isStop){
            }
        }
    }
}

简单的解释一下以上代码。
上面一共两个线程,一个是main一个是MyThread,他们共享一个变量 isStop,所以在main线程和MyThread都会有一个变量区,当我们修改了main线程的 isStop,它的变量区会被修改,共享内存区域里面就不一定修改(虽然概率及其的小),但是如果我们加上volatile修饰,isStop修改之后会立即同步到公共内存区,MyThread里面的变量区失效,重新获取公共区的isStop。

顺序性的具体实例,就举网上通用的例子,单例模式。
public class SingleInastace {
    private volatile static SingleInastace singleInastace = null;
    private SingleInastace(){
    }
    public static SingleInastace getSingleInastace(){
        if (singleInastace != null){
            synchronized(SingleInastace.class){
                if (singleInastace != null){
                    singleInastace = new SingleInastace();
                }
            }
        }
        return singleInastace;
    }
}

从以上代码看出,有可能发生顺序变换的 singleInstance = new SingleInstance();这句主要有三步操作。
1)给singleInstance 分配内存(栈空间)。
2)初始化SingleInstance()的构造函数。
3) singleInstance 对象指向堆空间(此时singleinstance)
当然正常的顺序是 1–>2–>3,也可能是 1–>3–>2,因为单线程的情况下运行的结果是一样的。但是如果多线程的情况下仍然按照 1–>3–>2的流程走,就会出问题。

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹