Volatile关键字

1. volatile
  • 保证可见性:程序会去主内存读取最新的改变
public class JMMDemo {
    /*
    * 不加volatile关键字,main线程将num改变,并写回主内存中,
    * 但是A线程并没有去主内存读取最新的num值,所以线程没有中断
    *
    * volatile:提醒线程A去主内存读取最新值
    * */
    private volatile static int num = 0;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while(num==0){

            }
        },"A").start();

        TimeUnit.SECONDS.sleep(2);
        num = 1;

    }


}
  • 不保证原子性
    • 原子性:不可分割,例如:事务,同时成功,同时失败
/*
* num应该为2000,但是num++再底层计算是分好几步的
* volatile 不保证原子性
* 解决方案:
* 1.加锁
* 2.用并发包的原子类,解决原子性问题,效率最高
* (原子类直接和操作系统底层挂钩,在内存中修改值,unsafe)
* */
public class VolatileDemo {
    //private volatile static int num = 0;
    private volatile static AtomicInteger num = new AtomicInteger();

    public static void main(String[] args) {

        for (int i = 0; i < 10 ; i++) {
            new Thread(()->{
                for (int j = 0; j < 2000; j++) {

                    VolatileDemo.add();
                }
            }).start();
        }

        //保证只剩下:main和gc线程,证明num是最终值
        while(Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println("num= "+num);
    }

    private static void add(){
        //num++;
        num.getAndIncrement();//AtomicInteger+1 方法,CAS,效率极高
    }
}

  • 禁止指令重排

    • 什么是指令重排:你写的程序并不是按照你写的那样去执行的
    • 源代码>编译器的优化重排>指令并行也可能重排>内存系统也会重排–>执行
    • volatile可以避免指令重排:内存屏障、CPU指令
    • 作用
      • 保证特定操作的执行顺序
      • 可以保证某些变量的内存可见性(利用这些变量实现了内存)
      • 根据自己的理解:Volatile修饰变量A,让A具有可见性,随时获取最新值,所以A不能改变自己的执行顺序,否则对其它影响比较大

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值