volatile关键字是如何保证程序的可见性

7 篇文章 1 订阅
7 篇文章 0 订阅

 volatile被喻为轻量级的"synchronized",虽然一定程度上要比synchronized关键字效率要高,但它也有不足之处,就是不具有互斥性和原子性。

volatile关键字的主要作用就是保证各线程之间的可见性,意思就是在多线程环境下,某个共享变量如果被其中一个线程给修改了,其他线程能够立即知道这个共享变量已经被修改了,当其他线程要读取这个变量的时候,最终会去内存中读取,而不是从自己的工作空间中读取,我们来看一段代码。

public class TestVolatile implements Runnable {
     private boolean flag = false;

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {

        }
        flag=true;
        System.out.println("flag=" + isFlag());
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }


  static class Thread2{
        public static void main(String[] args) {
            TestVolatile t1 = new TestVolatile();
            new Thread(t1).start();

            while (true) {


                if (t1.isFlag() == true) {
                    System.out.println(Thread.currentThread().getName()+"===============");
                   break;
                }
            }
        }
    }
}
这段代码正常的话应该输出主线程中的数据“===================”,然而运行之后并没有

原因就是main线程首先执行此时主存中的flag为false,run线程执行时把flag变成true在还没有提交到主线程时main线程又抢占到flag,此时的flag依旧为false,由于while(true)的执行效率特别高,高到方法体内的flag一直抢占不到true的时候,所以打印时就无法输出“============”。如图:

啥时候我们加一个synchronized也可以解决,但前面我们也提到了 synchronized太重量,所以此时我们可以在变量之前加一个volatile关键字使各线程之间的数据具有可见性,可理解为 run方法将flag变成true之后,主存中的flag立即变成true以便main线程能够及时看到。

private volatile boolean flag = false;

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值