volatile的作用

目录

1.保证内存可见性/指令重排序

2.不保证原子性


一.保证内存可见性/指令重排序

import java.util.Scanner;
public class demo16 {
    static class Counter{
        public static int flag = 0;
    }
    public static void main(String[] args) {
        Counter counter = new Counter();
        Thread t1 = new Thread(()->{
           while(counter.flag == 0){
               //执行循环,但是此处什么都不做;
           }
            System.out.println("t1结束");
        });
        t1.start();
        Thread t2 = new Thread(()->{
           //让用户输入一个数字,赋值给flag;
           Scanner scanner = new Scanner(System.in);
            System.out.println("请输入一个数字:");
            Counter.flag = scanner.nextInt();
        });
        t2.start();
    }
}

由上述程序:预期当用户给 t2线程输入一个非零数字之后,t1线程中counter.flag不满足等于0这个条件将会结束循环,随之线程结束。

但由运行结果可知:t1线程仍在循环,并没有结束。

 这是由于,t1的工作是:1.LOAD读内存中的数据到CPU寄存器中,2.TEST检测到CPU寄存器的值是否和预期一样。但是由于读内存比读CPU寄存器慢几千倍,几万倍,即当前的 t1的操作主要慢在LOAD上,编译器发现每次LOAD的结果都一样,就直接进行优化,相当于只从内存中读取一次,然后后续直接从寄存器里进行反复TEST。则会导致一种特殊情况,编译器看到这个线程没做修改,所以就进行了优化,但是其他的线程对这个变量修改了!

为了预防编译器误判,提供了一个干预优化的途径,即使用volatile关键字,来保证内存可见性。

volatile操作相当于显式的禁止了编译器进行优化,是给这个对应这个变量加上了“内存屏障”(特殊的二进制指令),JVM因为有这个内存屏障的存在,每次都会重新读取整个内存的结果,而不是草率的进行优化。

import java.util.Scanner;
public class demo16 {
    static class Counter{
        volatile public static int flag = 0;
    }
    public static void main(String[] args) {
        Counter counter = new Counter();
        Thread t1 = new Thread(()->{
           while(counter.flag == 0){
               //执行循环,但是此处什么都不做;
           }
            System.out.println("t1结束");
        });
        t1.start();
        Thread t2 = new Thread(()->{
           //让用户输入一个数字,赋值给flag;
           Scanner scanner = new Scanner(System.in);
            System.out.println("请输入一个数字:");
            Counter.flag = scanner.nextInt();
        });
        t2.start();
    }
}

 

二.不保证原子性

volatile不保证原子性,保证原子性的是synchronized。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值