博客
关于我
并发编程——Volatile原理
阅读量:799 次
发布时间: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/

    你可能感兴趣的文章
    Postman还能做Mock?又学了一招!
    查看>>
    Postman还能做Mock?又学了一招!
    查看>>
    postman进行http接口测试
    查看>>
    Postman高阶技能:Collection集合批量运行!
    查看>>
    postMessage跨标签页共享数据
    查看>>
    QImage对一般图像的处理
    查看>>
    post为什么会发送两次请求?
    查看>>
    Post表单提交TextArea的值出现转译乱码问题 - Spring MVC处理表单提交
    查看>>
    Power BI 中的 Python 可视化需要什么设置?任何特定的 matplotlib 包版本或系统设置?
    查看>>
    Power BI:如何在 Power Query 编辑器中将 Python 与多个表一起使用?
    查看>>
    power english (3) main text -emotion mastery - focus
    查看>>
    POWER ENGLISH (6) - MODEL
    查看>>
    power english (1) —— passion
    查看>>
    Power English (1) 原文
    查看>>
    power English (3)原文
    查看>>
    POWER ENGLISH(7)- repetition
    查看>>
    SpringBoot中集成SpringBatch详细解析与实战示例(CSV文件读取十万条数据进行业务处理后写入Mysql数据库)
    查看>>
    powerbi 一张表在另外一张表中出现的数量_PowerBi之初步学习笔记
    查看>>
    QGIS怎样设置简体中文以及新建可编辑的多边形的图层
    查看>>
    PowerBuilder 使用自定义事件触发键盘Enter事件
    查看>>