多线程(54)JMM中的内存屏障

Java内存模型(JMM)中的内存屏障是一种保证内存可见性、顺序性的底层机制。它们是一组指令,用于在多线程环境中确保内存操作的有序性和可见性。内存屏障主要分为四类:LoadLoad、StoreStore、LoadStore和StoreLoad。

内存屏障的类型

  1. LoadLoad屏障:确保LoadLoad屏障前的读操作不会被重排序到屏障后的读操作之后。
  2. StoreStore屏障:确保StoreStore屏障前的写操作不会被重排序到屏障后的写操作之后。
  3. LoadStore屏障:确保LoadStore屏障前的读操作不会被重排序到屏障后的写操作之后。
  4. StoreLoad屏障:确保StoreLoad屏障前的写操作不会被重排序到屏障后的读操作之后。这是最强的一种屏障,因为它同时阻止了前方的写和读操作被重排序到屏障之后。

内存屏障在Java中的应用

在Java中,volatile变量的读写,synchronized的锁的获取与释放,以及final字段的写操作,都会涉及到内存屏障的使用,来保证操作的有序性和可见性。

volatile变量

  • 写volatile变量:在写volatile变量之后,会插入一个StoreStore屏障,保证写操作之前的所有普通写(非volatile写)都完成;还会插入一个StoreLoad屏障,确保之后所有的读写操作都能看到这个volatile写。

  • 读volatile变量:在读volatile变量之前,会插入一个LoadLoad屏障,以及一个LoadStore屏障,确保volatile读操作之前的所有读操作都完成。

synchronized

  • 进入synchronized块:会插入一个LoadLoad屏障和一个LoadStore屏障,确保后续的读操作可以看到之前已经发生的写操作。

  • 退出synchronized块:会插入一个StoreStore屏障和一个StoreLoad屏障,保证锁释放之前的所有操作(包括所有的读写操作)都完成。

代码演示

Java代码本身并不直接操作内存屏障,但可以通过Unsafe类来模拟内存屏障的效果。以下是一个简化的示例,不是直接在Java代码中使用的实际模式,因为JMM的内存屏障是自动管理的。

java 复制代码
class MemoryBarrierExample {
    private volatile int flag = 0;
    private int ordinaryVar = 1;

    public void write() {
        ordinaryVar = 2; // 普通写操作
        flag = 1; // volatile写,带有StoreStore屏障和StoreLoad屏障
    }

    public void read() {
        int localFlag = flag; // volatile读,带有LoadLoad屏障和LoadStore屏障
        int localVar = ordinaryVar; // 普通读操作
        System.out.println("localFlag: " + localFlag + ", localVar: " + localVar);
    }
}

这个例子中,write方法先进行了一个普通的写操作,然后写入了一个volatile变量,这将插入必要的内存屏障。read方法首先读取了volatile变量,确保所有之前的写操作对当前线程可见,然后再进行普通的读操作。

总结

虽然Java程序员在编写日常代码时不直接与内存屏障打交道,了解内存屏障的工作原理对于理解JMM的内存可见性和操作的有序性至关重要。通过对volatile变量的操作、synchronized块的进入和退出,以及final字段的写操作,Java在底层自动插入相应的内存屏障,从而保证多线程环境中的内存一致性和线程安全。

相关推荐
浮尘笔记4 小时前
Go语言临时对象池:sync.Pool的原理与使用
开发语言·后端·golang
梦梦代码精5 小时前
BuildingAI vs Dify vs 扣子:三大开源智能体平台架构风格对比
开发语言·前端·数据库·后端·架构·开源·推荐算法
REDcker5 小时前
RESTful API设计规范详解
服务器·后端·接口·api·restful·博客·后端开发
没有bug.的程序员7 小时前
Java 序列化:Serializable vs. Protobuf 的性能与兼容性深度对比
java·开发语言·后端·反射·序列化·serializable·protobuf
我爱娃哈哈9 小时前
SpringBoot + Spring Security + RBAC:企业级权限模型设计与动态菜单渲染实战
spring boot·后端·spring
小王不爱笑13210 小时前
SpringBoot 配置文件
java·spring boot·后端
想用offer打牌10 小时前
Spring AI vs Spring AI Alibaba
java·人工智能·后端·spring·系统架构
码农幻想梦12 小时前
实验五 spring入门及IOC实验
java·后端·spring
a程序小傲12 小时前
蚂蚁Java面试被问:向量数据库的相似度搜索和索引构建
开发语言·后端·python·架构·flask·fastapi
派大鑫wink14 小时前
【Day39】Spring 核心注解:@Component、@Autowired、@Configuration 等
java·后端·spring