码迷,mamicode.com
首页 > 其他好文 > 详细

锁的内存语义

时间:2019-07-14 15:22:52      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:方式   机制   内存   互斥   过程   重要   获取   高效   无效   

锁是Java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。

锁的获取和释放

线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。

线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。

在共享变量的可见性方面,锁的释放和获取和volatile是类似的。

对volatile变量进行写操作,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。

对volatile变量进行读操作,JMM会把该线程对应的本地内存置为无效。再从主内存中读取共享变量。

 

锁获取和释放内存处理流程:

  • 线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息。
  • 线程B获取一个锁,实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息。
  • 线程A释放锁,随后线程B获取这个锁,这个过程实质上是线程A通过主内存向线程B发送消息。

 

concurrent包的实现

由于Java的CAS同时具有volatile读和volatile写的内存语义,因此Java线程之间的通信现在有了下面4种方式。
1)A线程写volatile变量,随后B线程读这个volatile变量。
2)A线程写volatile变量,随后B线程用CAS更新这个volatile变量。
3)A线程用CAS更新一个volatile变量,随后B线程用CAS更新这个volatile变量。
4)A线程用CAS更新一个volatile变量,随后B线程读这个volatile变量。

Java的CAS会使用现代处理器上提供的高效机器级别的原子指令,这些原子指令以原子方式对内存执行读-改-写操作,这是在多处理器中实现同步的关键。同时,volatile变量的读/写和CAS可以实现线程之间的通信。把这些特性整合在一起,就形成了整个concurrent包得以实现的基石。

分析concurrent包的源代码实现,会发现一个通用化的实现模式。

首先,声明共享变量为volatile。
然后,使用CAS的原子条件更新来实现线程之间的同步。同时,配合以volatile的读/写和CAS所具有的volatile读和写的内存语义来实现线程之间的通信。

AQS,非阻塞数据结构和原子变量类(java.util.concurrent.atomic包中的类),这些concurrent包中的基础类都是使用这种模式来实现的,而concurrent包中的高层类又是依赖于这些基础类来实现的。

                    concurrent包的实现示意图

技术图片

 

 

 

 

 

 

参考:

《Java并发编程艺术》

锁的内存语义

标签:方式   机制   内存   互斥   过程   重要   获取   高效   无效   

原文地址:https://www.cnblogs.com/simple-ly/p/11183468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!