Java JUC 源码分析 - synchronized、volatile内存语义及内存可见性

本文详细解释了Java并发编程中`synchronized`和`volatile`的关键作用,探讨了它们在内存可见性、互斥性和原子性方面的特性,并指出它们在JUC类和底层JVM实现中的应用。
摘要由CSDN通过智能技术生成

在Java并发编程中,synchronizedvolatile关键字是实现内存可见性和同步的关键工具,它们都是基于Java内存模型(Java Memory Model, JMM)的规定来保证多线程环境下的数据一致性。

synchronized关键字

synchronized关键字用于确保线程之间对共享资源的访问是互斥的,它可以应用于方法或者代码块。以下是其内存语义和可见性特点:

  1. 互斥性:同一时刻只允许一个线程访问被synchronized修饰的代码块或方法,阻止了并发访问带来的数据不一致性问题。

  2. 可见性:当线程A退出一个synchronized块或方法时,对共享变量所做的更改对随后进入该synchronized块或方法的任何线程(包括线程A本身)都是可见的。这是因为退出synchronized区域时会执行内存屏障操作,确保本地缓存的数据刷新到主内存。

  3. 原子性:对于简单的基本类型变量的读写操作(如int、long等),在synchronized代码块中通常是原子的。但对于复合操作(如++、–等),则需要整个操作都在synchronized块中才能保证原子性。

  4. 内存语义synchronized会确保“先行发生原则”(Happens-Before)的成立,即对一个监视器锁的解锁操作先行发生于随后对同一个锁的加锁操作。

volatile关键字

volatile关键字主要用来保证变量的可见性和一定程度的有序性,但不提供互斥性:

  1. 可见性:当一个线程修改了volatile变量的值时,其他线程总是能看到最新值,因为它强制从主内存读取变量的值,而不是使用寄存器或高速缓存中的副本。对volatile变量的写入会flush掉线程的工作内存,并且会使其他线程load该变量时从主内存中读取。

  2. 禁止指令重排序volatile关键字还能防止编译器和处理器对指令进行重排序优化,确保代码的执行顺序与程序员的书写顺序一致,尤其是在多线程环境中有重要意义。

  3. 不保证原子性:虽然volatile变量的读写是原子的,但是对于复合操作(例如递增、递减等)来说,并不是一个原子操作,因此无法保证线程安全性。

在JUC源码分析中,可以看到synchronizedvolatile在很多并发类和工具类中起到了至关重要的作用,如AtomicIntegerCountDownLatch等内部都利用了volatile关键字来实现高效的无锁同步。同时,JVM在底层实现上,会依据Java内存模型规范,为synchronizedvolatile生成相应的内存屏障指令,确保并发控制的有效性。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值