专栏首页WindCoder并发学习笔记08-锁的内存语义

并发学习笔记08-锁的内存语义

锁可以让临界区互斥执行,还可以让释放锁的线程向获取同一个锁的线程发送消息。

锁的内存语义

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

线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息。

线程B获取一个锁,实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息。

线程A释放一个锁,随后线程B获取该锁,这个过程实质是线程A通过主内存向线程B发送消息。

由上可见,锁的释放-获取的内存语义同volatile变量写-读的内存语义相同。

内存语义的实现

  • 公平锁和非公平锁释放时,最后都要写一个volatile变量state。
  • 公平锁获取时,首先会去读volatile变量。
  • 非公平锁获取时,首先会用CAS更新volatile变量,这个操作同时具有volatile读和volatile写的内存语义。

锁释放-获取的内存语义的实现至少有下面两种方式:

  • 利用volatile变量的写-读所具有的内存语义。
  • 利用CAS所附带的volatile读和volatile写的内存语义。

concurrent包的实现

由于Java的CAS同时具有volatile读和volatile写的内存语义,因此Java线程之间的通信现在有了下面4中方式:

  • A线程写volatile变量,随后B线程读这个volatile变量。
  • A线程写volatile变量,随后B线程用CAS更新这个volatile变量。
  • A线程用CAS更新一个volatile变量,随后B线程用CAS更新这个volatile变量。
  • A线程用CAS更新一个volatile变量,随后B线程读这个volatile变量。

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

观察concurrent包的源码实现,可发现一个通用化的实现模型:

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

AQS,非阻塞数据结构和原子变量类,这些concurrent包中的基础类都是使用这些模式来实现的,其高层类又是基于这些基础类来实现的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 并发学习笔记07-volatile的内存语义

    对volatile变量的单个读/写,可看成是使用同一个锁对这些单个读/写操作做了同步。如示例:

    汐楓
  • 并发学习笔记12-线程基础(上)

    现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight Process)。

    汐楓
  • 并发学习笔记13-线程基础(下)

    Volatile可以修饰字段(成员变量),就是告知程序任何对该变量的访问均需从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可...

    汐楓
  • 深入分析Volatile的实现原理

    在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享...

    heasy3
  • 为了讲清volatile,面试官都听不下去了

    根据JMM中规定的happen before和同步原则: 对某个volatile字段的写操作happens- before每个后续对该volatile字段的读...

    JavaEdge
  • 最详细分析Java 内存模型

    并发编程中, 线程之间如何通信及线程之间如何同步, 通信是指线程之间以何种机制来交换 信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。

    黑白格
  • 深入理解Java多线程中的volatile关键字Java 的 volatile关键字对可见性的保证Java 的 volatile关键字在保证可见性之前的所做的事情Volatile有时候也是不够的什么时

    Java关键字用于将一个变量标记为“存储在内存中的变量”。更准确的说,意思就是每一次对volatile标记的变量进行读取的时候,都是直接从电脑的主内存进行的,而...

    desperate633
  • Java并发编程,3分分钟深入分析volatile的实现原理

    Java内存模型告诉我们,各个线程会将共享变量从主内存中拷贝到工作内存,然后执行引擎会基于工作内存中的数据进行操作处理。 线程在工作内存进行操作后何时会写到主内...

    李红
  • Java中volatile关键字的最全总结

    volatile是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchroni...

    哲洛不闹
  • 你知道Java并发三大问题么,volatile和CAS又是什么?

    如果是在一个串行执行的语言中,执行SetCheck类中的check方法永远不会返回false,即使编译器,运行时和计算机硬件并没有按照你所期望的逻辑来处理这段程...

    Java技术江湖

扫码关注云+社区

领取腾讯云代金券