博客
关于我
Java volatile使用详细说明-可见性的详细讲解
阅读量:696 次
发布时间:2019-03-17

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

Java多线程之同步与易失性

在学习多线程编程时,同步和易失性是两个关键概念。前篇已经探讨了同步的骚操作,本篇将深入分析同步状语从句,了解其与易失性之间的区别,易失性的使用条件,以及虚拟机层面的一些实现细节。


本文要点

  • 同步与易失性特性差异
  • 使用易失性需要满足的条件
  • 易失性特性在虚拟机层面的实现
  • 易失性示例代码

  • 1. 同步与易失性特性差异

    1.1 可见性和原子性

    • synchronized保证了可见性和原子性。
    • volatile仅保证可见性,不具备原子性。
    • 可见性是指,一个线程修改了被volatile修饰的变量后,其他线程可以立即发现新值。

    1.2 线程阻塞

    • synchronized可能会导致线程阻塞,因为它争夺资源时会让其他线程等待。
    • volatile不会引起阻塞,因为它不会影响线程的执行流程。

    1.3 依赖性与安全性

    • 当共享数据的改变依赖于其之前的值时,synchronized能保证线程安全,而volatile不适用于这种场景。
    • volatile主要用于标记完成或中断等场景,例如资源是否被释放或信号是否正确传递。

    1.4 修饰方式与重排序

    • synchronized修饰的是方法或代码块,而volatile修饰的是变量。
    • volatile修饰的变量不会被重排序,减少了同步有关的复杂性。

    1.5 虚拟机的规则

    • 从虚拟机的规则来看,volatile变量的写操作总是比后续的读操作先发生。这体现了内存的一致性模型。

    2. 使用易失性需要满足的条件

    2.1 单一修改-authority

    • 变量的修改不能依赖其当前值,并且只能有单一线程能够执行修改操作。

    2.2 不变约束

    • 变量不需要与其他变量完成不变式约束。例如,不需要保证 x + y = k 总是成立,除非这是非多线程环境下的绝对需求。

    2.3 无需额外锁定

    • 使用volatile时不需要额外的锁定机制,因为它不需要保护代码块的可执行性。

    3. 易失性特性在虚拟机层面的实现

    虚拟机通过以下机制确保易失性变量的一致性:

    • 当一个线程修改了被volatile修饰的变量时,其修改操作会立即反映到主内存中。
    • 其他线程在访问该变量时,会直接从主内存中读取当前值,而不是从工作内存中缓存副本。
    • 正常变量的读写操作可能因工作内存的缓存而遮蔽,容易导致多线程环境下的一致性问题。

    4. 易失性示例代码

    4.1 共享变量作为开关

    以下示例代码展示了volatile变量作为开关的应用:

    public class ValiableTest {    public static void main(String[] args) {        boolean isRunning = false;        Thread t1 = new Thread(() -> {            while (isRunning) {                System.out.println("运行中......");                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        });                new Thread(() -> {            isRunning = false;            System.out.println("下面终止运行");        }).start();                t1.start();    }}
    • volatile修饰:如果不使用volatileisRunning变量在多线程环境下可能不会更新,导致程序无法正常终止。
    • 使用volatile修饰:若isRunningvolatile修饰,主线程的修改会及时反映到其他线程,程序才能正常终止。

    总结

    通过对比synchronizedvolatile的特性,我们可以更好地理解它们各自适用的场景。synchronized更适合保护共享资源的原子性操作,而volatile则用以处理快速变更的状态标记,如资源释放或信号传递。在实际编码中,应该根据具体需求选择合适的机制。

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

    你可能感兴趣的文章
    Power English (1) 原文
    查看>>
    power English (3)原文
    查看>>
    POWER ENGLISH(7)- repetition
    查看>>
    SpringBoot中集成SpringBatch详细解析与实战示例(CSV文件读取十万条数据进行业务处理后写入Mysql数据库)
    查看>>
    powerbi 一张表在另外一张表中出现的数量_PowerBi之初步学习笔记
    查看>>
    QGIS怎样设置简体中文以及新建可编辑的多边形的图层
    查看>>
    PowerBuilder 使用自定义事件触发键盘Enter事件
    查看>>
    PowerCreatorCMS UploadResourcePic 任意文件上传漏洞复现
    查看>>
    PowerDesigner 使用的一些技巧(转)
    查看>>
    QGIS在Windows上下载安装与建立空间数据库连接
    查看>>
    PowerDesigner165安装婆姐汉花教程
    查看>>
    PowerDesigner使用教程:设置注释、默认值属性
    查看>>
    PowerDesigner使用教程:不显示背景网格
    查看>>
    PowerDesigner使用教程:创建数据模型以及导出
    查看>>
    PowerDesigner使用教程:右侧工具栏显示/隐藏
    查看>>
    PowerDesigner使用教程:导出sql文件以及解决中文乱码问题
    查看>>
    PowerDesigner使用教程:时间字段设置
    查看>>
    PowerDesigner使用教程:给字段添加唯一约束
    查看>>
    QGIS中怎样设置图层样式并导出地图样式
    查看>>
    PowerDesigner使用笔记
    查看>>