博客
关于我
并发编程——Volatile原理
阅读量:798 次
发布时间:2023-03-28

本文共 1565 字,大约阅读时间需要 5 分钟。

Volatile关键字深度解析:可见性与非原子性的权衡

JMM内存模型:理解Java内存管理的核心

在Java编程中,内存模型是Java Virtual Machine (JVM) 规范中定义的核心概念。它屏蔽了底层计算机的差异,为程序提供了一致的内存抽象。现代计算机系统为了提高性能,引入了高速缓存(cache),将内存与处理器之间作为缓冲层。这种设计虽然提高了性能,但也带来了缓存一致性(Cache Coherence)的复杂性。

在多处理器系统中,每个处理器都有自己的缓存,而所有处理器共享同一主内存。Java内存模型(JavaMemoryModel)定义了共享变量的访问规则。所有共享变量(如实例变量和类变量)存储在主内存中,而线程有自己的工作内存,用于存储被线程使用的变量副本。线程对变量的读写操作必须在工作内存完成,线程间变量的传递需要通过主内存完成。

Volatile的可见性原理:保证线程间数据一致性

Volatile关键字通过两个关键特性确保线程间的可见性和有序性:

  • 读取和写入的连续性

    • 在读操作(load)之前,必须先执行读操作(read)。
    • 在写操作(write)之后,必须执行写操作(store)。

    这种连续性保证了工作内存在读取前必须刷新主存的最新值,写入后必须同步到主存。

  • 禁止指令重排:Volatile插入内存屏障,阻止编译器对指令进行重排优化。这样可以防止缓存层面上的数据不一致问题。

  • Volatile的非原子性:理解其局限性

    尽管Volatile保证了可见性和有序性,但它本身并不提供原子性操作。由于非原子性,以下操作可能导致数据竞争:

  • use和assign的非连续性

    • 主存读取num的值。
    • 执行num++运算。
    • 将num值写入主存。

    如果多个线程同时进行这些操作,可能导致脏数据的读写不一致。

  • 线程安全的适用范围

    • 当运算结果不依赖于变量的状态或不依赖于其他状态变量时。
    • 当变量的值传递不受其他操作的影响时。
  • Volatile与Synchronized的配合使用:双重保障

    在需要更高级别的线程安全时,Volatile通常与Synchronized结合使用。Synchronized通过获取对象锁,确保代码块串行执行,并禁止指令重排,从而保证线程安全。

    例如,在单例模式中,双检查锁(Double Checked Locking)结合Volatile可以有效防止多线程实例化过程中的竞态条件:

    public class Singleton {    private volatile static Singleton instance = null;    private Singleton() {}    public static Singleton getInstance() {        if (instance == null) {            synchronized (Singleton.class) {                if (instance == null) {                    instance = new Singleton();                }            }        }        return instance;    }}

    这种设计通过Volatile防止指令重排,确保单例实例化的正确性。

    总结

    Volatile是Java中一个强大的工具,但其可见性和有序性并不意味着原子性。正确使用Volatile需要结合上下文,特别是在涉及线程安全时,通常需要与Synchronized配合。理解Volatile的特性和局限性,对于实现高效且线程安全的Java程序至关重要。

    转载地址:http://dlhfk.baihongyu.com/

    你可能感兴趣的文章
    phoenix无法连接hbase shell创建表失败_报错_PleaseHoldException: Master is initializing---记录020_大数据工作笔记0180
    查看>>
    Phoenix简介_安装部署_以及连接使用---大数据之Hbase工作笔记0035
    查看>>
    phoenix连接hbase报错Can not resolve hadoop120, please check your network_记录026---大数据工作笔记0187
    查看>>
    Photoshop工作笔记001---Photoshop常用快捷键总结
    查看>>
    Reids配置文件redis.conf中文详解
    查看>>
    Photoshop脚本入门
    查看>>
    PHP
    查看>>
    Regular Expression Notes
    查看>>
    PHP $FILES error码对应错误信息
    查看>>
    PHP $_FILES函数详解
    查看>>
    PHP $_SERVER['HTTP_REFERER'] 获取前一页面的 URL 地址
    查看>>
    php & 和 & (主要是url 问题)
    查看>>
    php -- 魔术方法 之 判断属性是否存在或为空:__isset()
    查看>>
    php -- 魔术方法 之 获取属性:__get()
    查看>>
    php -树-二叉树的实现
    查看>>
    PHP -算法-二路归并
    查看>>
    php 2条不一样 的json数据 怎么放在一个json里面_如果你是PHP开发者,请务必了解一下Composer...
    查看>>
    php 360 不记住密码,JavaScript_多种方法实现360浏览器下禁止自动填写用户名密码,目前开发一个项目遇到一个很 - phpStudy...
    查看>>
    regExp的match、exec、test区别
    查看>>
    php 404 自定义,APACHE 自定义404错误页面设置方法
    查看>>