前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1.JUC线程高级-volatile关键字与内存可见性

1.JUC线程高级-volatile关键字与内存可见性

作者头像
用户1212940
发布2022-04-13 15:02:51
1370
发布2022-04-13 15:02:51
举报
文章被收录于专栏:Lambda

1. 多线程操作共享变量引发问题

我们通过下面代码来分析下内存可见性问题:

代码语言:javascript
复制
    package com.pyy.juc;
    
    public class TestVolatile {
    
        public static void main(String[] args) {
    
            // 这个线程为flag 修改值
            ThreadDemo td = new ThreadDemo();
            new Thread(td).start();
    
    
            // 主线程无线循环判断这个flag值
            while(true) {
                if(td.isFlag()) {
                    System.out.println("============");
                    break;
                }
            }
        }
    }
    
    class ThreadDemo implements Runnable {
        private boolean flag = false;
    
        @Override
        public void run() {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            flag = true;
    
            System.out.println("flag=" + isFlag());
        }
    
        public boolean isFlag() {
            return flag;
        }
    }

运行代码,会发现控制台输出:flag=true,但程序(主线程)并没有结束。这里就涉及到多线程的内存可见性问题:

11464886-82580a19b2317056.png
11464886-82580a19b2317056.png

出现上述问题的原因,主要是因为多个线程操作共享数据彼此不可见

解决内存可见性问题可以使用同步锁(synchronized)

代码语言:javascript
复制
        while(true) {
            synchronized(td) {
                if(td.isFlag()) {
                    System.out.println("============");
                    break;
                }
            }
        }

通过同步锁方式(可以保证每次都刷新主存,保证共享数据的同步性),但只要用到锁就会引发线程等待,影响代码效率。

2. volatile关键字

这里就引出了一个新的关键字volatile,它就可以保证多个线程操作共享数据内存中的数据是彼此可见的。底层是通过内存屏障,我们可以理解volatile修饰的变量是在主存中的数据直接操作。

读写变量都在 主存中直接操作,进而保证多线程可见性。而且效率上要比同步锁高的多。

11464886-84fbe55dbbc8595c.png
11464886-84fbe55dbbc8595c.png

其实有说volatile效率底,是因为jvm底层有个指令排序,但使用volatile修饰的变量会有一个禁止指令重排限制

3. 代码重构后

代码语言:javascript
复制
    ...
    // 使用volatile修饰变量
    private volatile boolean flag = false;
    ...

就可以解决多个线程操作共享数据彼此不可见问题

4. volatile和synchronized区别

volatile只是一个相比synchronized来说较为轻量级的同步策略

  1. volatile 不具备互斥性
  2. volatile 不能保证修饰变量的原子性

后面我们在谈论下有关变量原子性和CAS算法问题

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/09/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 多线程操作共享变量引发问题
    • 2. volatile关键字
      • 3. 代码重构后
        • 4. volatile和synchronized区别
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档