volatile 关键字

目录

内存可见性问题

1、产生原因

2、解决方法


volatile关键字可以保证内存的可见性

内存可见性问题

1、产生原因

计算机在运行是程序和代码,要经常访问数据,这些依赖的数据,往往会存储在内存中

cpu使用数据的时候,就会把这个内存中的数据,先读取出来,然后放到cpu的寄存器中,再参与运算,但cpu读取内存的时候是非常慢的。

为了解决上述问题,提高效率,此时编译器就可能对代码进行优化,把一些本来要读取内存的操作,优化成读取寄存器,减少读取内存的次数,也就可以提高整体程序的效率。但当对内存中的数据进行操作时,编译器并没有读取更新后的内存,而是继续读取编译器,就形成了没有更新成功的现象,这就是“内存可见性问题“。


例如:

import java.util.Scanner;

public class demo {

    private static int isQuit=0;

    public static void main(String[] args) {

        Thread t1=new Thread(()->{

           while (isQuit==0){
               //一直循环
           }

            System.out.println("t1退出");

        });

       t1.start();

       Thread t2=new Thread(()->{

           System.out.println("请输入isQuit");

           Scanner scanner=new Scanner(System.in);

           isQuit=scanner.nextInt();

       });

       t2.start();
    }
}

在循环中

1、通过load读取内存中的isQuit的值到寄存器

2、通过cmp指令比较寄存器的值是否为0,决定是否需要继续循环

由于这个循环的速度飞快,短时间内会产生大量的循环,也就是大量的load和cmp操作

此时,编译器就发现了,多次load的结果都是一样的,非常浪费时间。所以编译器就进行了优化,只让第一次的循环的时候读取了内存,后续直接在寄存器上取值,无法感受到内存的变化。

当t2线程修改isQuit为非0的值的时候,t1线程也并没有结束,此处就发生了”内存可见性问题”。


2、解决方法

volatile就是解决方案

通过volatile关键字,可以告诉编译器不要优化。

只需要给isQuit关键字加上volatile关键字修饰

private volatile static int isQuit=0;

import java.util.Scanner;

public class demo {

    private volatile static int isQuit=0;

    public static void main(String[] args) {

        Thread t1=new Thread(()->{

           while (isQuit==0){
               //一直循环
           }

            System.out.println("t1退出");

        });

       t1.start();

       Thread t2=new Thread(()->{

           System.out.println("请输入isQuit");

           Scanner scanner=new Scanner(System.in);

           isQuit=scanner.nextInt();

       });

       t2.start();

    }
}

此时将isQuit改为非0的值时,while循环就会结束。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值