读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.4 volatile的内存语义

本文解析了volatile关键字的可见性和原子性特点,并探讨了它如何通过建立happens-before关系实现线程间的通信。此外,还介绍了volatile的内存语义及其实现机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.4 volatile的内存语义

3.4.1 volatile的特性

理解volatile特性的一个好方法是对volatile变量的单个读、写,看成是使用同一个锁对这些单个读、写操作做了同步。

class VolatileFeaturesExample{
    volatile long v1 = 0L;   //使用volatile声明64位的long型变量

    public void set(long l){
        v1 = l;              //单个volatile变量的写
    }
    public void getAndIncrement(){
        v1++;               //复合(多个)volatile变量的读、写
    }

    public long get(){
        return v1;          //单个volatile变量的读
    }
}

假设有多个线程分别调用上面程序的3个方法,这个程序在语义上和下面的程序等价。

class VolatileFeaturesExample(){
    long v1 = 0L;

    public synchronized void set(long l){   //对单个的普通变量的写用一个锁同步
        v1 = l;
    }

    public void getAndIncrement(){          //普通方法调用
        long temp = get();                  // 调用已经同步的读方法
        temp += 1L;                         // 普通的写操作
        set(temp);                          // 调用已经同步的写方法
    }

    public synchronzied long get(){
        return v1;
    }

}

简而言之,volatile变量自身具有如下特性:

  1. 可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量的最后的写入
  2. 原子性:对任意**单个**volatile变量的读、写具有原子性

3.4.2 volatile写-读建立的happens-before关系

从JSR-133(即JDK5开始),volatile变量的读、写可以实现线程之间的通信。

如下代码:

class VolatileExample(){
    int a = 0;
    volatile boolean flag = false;

    public void writer(){
        a = 1;               // 1
        flag = true;         // 2
    }

    public void reader(){
        if(flag){            // 3
            int i = a ;      // 4 
            .....
        }
    }
}

假设线程A执行writer()方法之后,线程B执行reader()方法,其happens-before关系的图形化表现形式如下:

这里写图片描述

3.4.3 volatile写-读的内存语义

  1. 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。
  2. 当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来从主内存中读取共享变量。

这里写图片描述

3.4.4 volatile内存语义的实现

为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。

3.4.5 JSR-133为什么要增强volatile的内存语义

为了提供一种比锁更轻量级的线程之间通信的机制

在功能上,锁比volatile更强大;在可伸缩性和执行性能上,volatile更有优势。

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广泛的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值