volatile关键字——解决内存可见性问题

目录

内存可见性问题

解决方案——volatile关键字


内存可见性问题

计算机要访问的数据在内存中,cpu使用这个变量的时候,会把内存中的数据读出来,放在寄存器中,再参与运算(load)

读寄存器速度 远快于 读内存速度 远快于 读硬盘速度

所以读/写内存操作会降低cpu速度

为了解决上述问题,提高效率,编译器把原来要读内存的操作,优化 成读寄存器,减少读内存的次数

典型问题

public class myself2 {
    static int isQuit=0;
    public static void main(String args[]) throws InterruptedException {
        Thread t=new Thread(()->{
           while (isQuit==0){
               //System.out.println("线程工作中");
           }
            System.out.println("线程要结束了");
        });
        t.start();
        System.out.println("请输入isQuit");
        Scanner scanner=new Scanner(System.in);
        isQuit=scanner.nextInt();
    }
}

当在主线程中输入isQuit为1后 t线程本来应该退出 但程序始终在运行中 这就是内存可见性问题引起的!!(之前两个线程同时修改一个变量会有线程安全问题 此时针对同一个变量 一个线程读 一个线程写也会有线程安全问题)


解决方案——volatile关键字

通过volatile关键字 告诉编译器不要优化(编译器什么时候优化并不知道 我们直接通过volatile告诉编译器不要优化)

static volatile int isQuit=0;

此时,就可以顺利退出了

此外,当在线程中加入sleep,我们也会发现顺利退出了

这是因为,加入sleep之后,while循环速度慢了,load次数少了,开销少了,编译器也没必要进行优化了编译器什么时候优化并不知道 我们直接通过volatile告诉编译器不要优化)

public class myself2 {
    static  int isQuit=0;
    public static void main(String args[]) throws InterruptedException {
        Thread t=new Thread(()->{
           while (isQuit==0){
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               //System.out.println("线程工作中");
           }
            System.out.println("线程要结束了");
        });
        t.start();
        System.out.println("请输入isQuit");
        Scanner scanner=new Scanner(System.in);
        isQuit=scanner.nextInt();
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值