博客
关于我
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/

    你可能感兴趣的文章
    php取当天的最后一秒_Docker快速搭建PHP开发环境详细教程
    查看>>
    php取绝对值
    查看>>
    PHP变量内容的获取
    查看>>
    php各种常用的算法
    查看>>
    php各种缓存策略对比
    查看>>
    RabbitMQ高级特性 - 消息分发(限流、负载均衡)
    查看>>
    php后台“爬虫”模拟登录第三方系统
    查看>>
    php后台的在控制器中就可以实现阅读数增加
    查看>>
    php命令行生成项目结构
    查看>>
    php命名空间
    查看>>
    PHP命名空间带来的干扰
    查看>>
    PHP和MySQL Web开发从新手到高手,第1天-搭建PHP开发环境
    查看>>
    php商店管理系统,基于PHP的商店管理系统.doc
    查看>>
    PHP四大主流框架的优缺点总结
    查看>>
    PHP图片处理—PNG透明缩放并生成灰图
    查看>>
    php在liunx系统中设置777权限不起作用解决方法
    查看>>
    PHP基于openssl实现的非对称加密操作
    查看>>
    php基本符号大全
    查看>>
    php基础篇-二维数组排序 array_multisort
    查看>>
    php基础配置环境变量
    查看>>