Java volatile作用

Java volatile作用javavolatile作用

大家好,又见面了,我是你们的朋友全栈君。

1、一个变量声明为volatile,就意味着这个变量被修改后其他所有使用到此变量的线程都立即可见

2、禁止指令重排序,防止在运行时不是按照代码的先后顺序执行

 

volatile是一种轻量级的同步机制,不会引起的线程上下文切换,可以保证可见性和禁止重排序,但不能保证原子性带来的线程安全问题。

volatile特性

可见性
当有多个线程访问同一个变量时,一个线程对此变量的修改,其他线程应该立刻可获取到修改后的值。
一个变量用volatile修饰后,当对此变量写入时,会立刻将写入后的值刷新到主存中,并且将其他线程本地内存中保存的值失效,其他线程读取此变量时,会直接从主内存中读取。

public class VolatileDemo {
    private static boolean stop = true;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while(stop){//无限循环
            }
        }).start();
        //确保上面线程先执行
        Thread.sleep(100);
        //虽然修改为false,但是上面线程依旧不会停
        stop = false;
        System.out.println("main thread end...");
    }
}

在这里插入图片描述
这就是可见性问题,只需要加上volatile修饰符即可。【亲测,确实是!】

private volatile static boolean stop = true;

 

在这里插入图片描述

指令重排序
编译器有时会为了效率,在保证不影响最终结果的前提下,会改变代码的执行顺序。
在单线程下,不会存在问题,但是在多线程下就会带来一些问题,比如单例模式中,双重锁校验,锁的对象必须用volatile修改。

单例模式:双重锁校验

public class DoubleCheck {
    private static volatile DoubleCheck doubleCheck = null;
    private DoubleCheck() {
    }
    public static DoubleCheck getInstance() {
        //第一次校验
        if (doubleCheck == null) {
            synchronized (DoubleCheck.class) {
                //第二次校验
                if (doubleCheck == null) {
                    doubleCheck = new DoubleCheck();
                }
            }
        }
        return doubleCheck;
    }
}

doubleCheck = new DoubleCheck();可以分解为3行伪代码
1、memory = allocate() //分配内存
2、ctorInstanc(memory) //初始化对象
3、doubleCheck = memory //设置doubleCheck指向刚分配的地址

转自:https://blog.csdn.net/CSDN_WYL2016/article/details/107006025

Java单例模式(一)饿汉式、懒汉式(双重校验锁)

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161271.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月18日 上午8:46
下一篇 2022年7月18日 上午8:46


相关推荐

  • Custom Cursor怎么用到桌面?宝藏教程,手把手教你实现个性化鼠标指针!

    Custom Cursor怎么用到桌面?宝藏教程,手把手教你实现个性化鼠标指针!

    2026年3月16日
    2
  • 大数据分析在职业体育应用

    大数据分析在职业体育应用大数据分析在职业体育应用(NBA)什么是大数据?举个例子,都说骑士队依赖詹姆斯,当詹姆斯在场上时,骑士队每100回合净胜对手6.9分;詹姆斯不在场,骑士队净负对手2.9分,两者之间差值为9.8分。而勇士队的库里在场上和在场下时,勇士队每100回合净胜分的差值为17分,可以说勇士队对库里的依赖甚至要更强。这样的数据才可以叫大数据,相比而言,像得分、篮板、助攻这样的技术统计简直弱爆了。大数据在N…

    2022年5月9日
    86
  • 常用的.net开源项目「建议收藏」

    常用的.net开源项目「建议收藏」Json.NEThttp://json.codeplex.com/Json.Net是一个读写Json效率比较高的.Net框架.Json.Net使得在.Net环境下使用Json更加简单。通过LinqToJSON可以快速的读写Json,通过JsonSerializer可以序列化你的.Net对象。让你轻松实现.Net中所有类型(对象,基本数据类型等)和Json的转换。

    2022年7月15日
    24
  • 评分卡模型python实现

    评分卡模型python实现在公众号 python 风控模型 里回复关键字 学习资料 就可免费领取 python 风控模型持牌照金融公司模型专家 教学主页 https ke com teacher tuin dcbf0

    2026年3月17日
    3
  • nextSibling 和nextElementSibling的区别[通俗易懂]

    nextSibling 和nextElementSibling的区别[通俗易懂]使用nextSibling属性返回指定节点之后的下一个兄弟节点,(即:相同节点树层中的下一个节点)。nextSibling属性与nextElementSibling属性的差别: nextSibling属性返回元素节点之后的兄弟节点(包括文本节点、注释节点即回车、换行、空格、文本等等); nextElementSibling属性只返回元素节点之后的兄弟元素节点(不包括文本节点、注释节点);注意:空…

    2022年7月13日
    15
  • 开源网管软件_网关开发

    开源网管软件_网关开发让你不差钱的9款开源网管工具(组图)http://network.51cto.com/art/200906/129490.htm 转载于:https://blog.51cto.com/zgxworks/167764

    2026年4月15日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号