java volatile 关键字

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的流程走,就会出问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值