一 引言

  在说volatile的内存语义时,讲过这样一句话:想要理解透volatile特性有一个很好的方法,就是把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步。所以其实锁的释放和获取与volatile的写和读具有相同的内存语义。

二 锁的释放-获取建立的happens-before关系

  不清楚happens-before规则的请前去看-看,这里就不在细说了。由于在之前没有举例说明监视器锁规则,那么在这里就详细说明下,下面是锁释放-获取的示例代码:

public class MonitorExample {
int a = 0; public synchronized void writer() { //
a += 1; //
} // public synchronized void reader() { //
System.out.println(a); //
} // public static void main(String[] args) {
final MonitorExample me = new MonitorExample();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
me.writer();
}
});
t1.start(); Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
me.reader();
}
});
t2.start();
}
}

  这里我们假设线程1先执行writer()方法,随后线程B执行reader()方法(知道为什么要假设?因为不是一定按这种顺序发生,可以测试下结果)。根据happens-before规则,这个过程包含的happens-before关系可以分为3类:

  1) 根据程序次序规则:1 happens-before 2, 2 happens-before 3, 4 happens-before 5, 5 happens-before 6;

  2)根据监视器锁规则:3 happens-before 4;

  3)根据传递性规则,2 happens-before 5。

  上述happens-before关系的图形化表现形式如下:

三 锁的释放和获取的内存语义

  当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。以上面的MonitorExample程序为例,线程1释放锁后,共享数据的状态示意图如下:

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

  对比锁释放-读取的内存语义与volatile写-读的内存语义可以看出,锁释放与volatile写具有相同的内存语义;锁获取与volatile读具有相同的内存语义。下面对锁释放和锁获取的内存语义做个总结。

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

四 锁内存语义的实现

  锁有很多种,但其基本原理都是差不多的。书上是以ReentrantLock中的公平锁与非公平锁作为案例分析,有兴趣的同学可以去阅读原籍和源码。现总结如下:

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

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

  1)利用volatile变量的写-读所具有的内存语义。

  2)利用CAS所附带的volatile读和volatile写的内存语义。

  由此可知:并发包下的类的实现方式大部分都是基于这两种方式实现的。

Java内存模型-锁的内存语义的更多相关文章

  1. Java内存模型-volatile的内存语义

    一 引言 听说在Java 5之前volatile关键字备受争议,所以本文也不讨论1.5版本之前的volatile.本文主要针对1.5后即JSR-133针对volatile做了强化后的了解. 二 vol ...

  2. java内存模型-锁

    锁的释放-获取建立的 happens before 关系 锁是 java 并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息.下面是锁释放-获取的示 ...

  3. 【java】java内存模型(2)--volatile内存语义详解

    多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”.可见性的意思是当一个线程 ...

  4. Java 内存模型和硬件内存架构笔记

    前言 可跟<主存存取和磁盘存取原理笔记>串着看 https://blog.csdn.net/suifeng3051/article/details/52611310 杂技 Java 内存模 ...

  5. Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系

    CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...

  6. JAVA内存模型与JVM内存结构

    问题:什么事java内存模型? 首先呢不要答堆.栈.方法区.这是JVM的内存结构.下面阐述了JMM和JVM的区别和自己对JMM的见解 1.Java内存模型(JMM):即多线程相关的.定义了一个线程对另 ...

  7. Java内存模型、JVM内存结构和Java对象模型

    JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存 ...

  8. 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈

    C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...

  9. 04-JVM内存模型:直接内存

    1.1.什么是直接内存(Derect Memory) 在内存模型最开始的章节中,我们画出了JVM的内存模型,里面并不包含直接内存,也就是说这块内存区域并不是JVM运行时数据区的一部分,但它却会被频繁的 ...

随机推荐

  1. PAT甲级题解-1057. Stack (30)-树状数组

    不懂树状数组的童鞋,正好可以通过这道题学习一下树状数组~~百度有很多教程的,我就不赘述了 题意:有三种操作,分别是1.Push key:将key压入stack2.Pop:将栈顶元素取出栈3.PeekM ...

  2. How to delete deployed process definition in activiti?

    https://community.alfresco.com/thread/219767-how-to-delete-deployed-process

  3. Guava的SetMultimap

    在工作中,我们会经常用到如下类似的结构 Map<String, Set<Stirng>> map = new HashMap<Stirng, Set<String& ...

  4. P2622 关灯问题II

    题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...

  5. 骑士 HYSBZ - 1040(基环树+树形dp)

    Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...

  6. Gym 100463A Crossings (树状数组 逆序对)

    Crossings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463 Description ...

  7. THUWC2019爆零记

    Day -1 现在在机房里,准备敲敲板子什么的. 今天晚上放假诶,要好好睡一下.好好睡是不可能的,这辈子不可能的. Day 0 现在在酒店,\(lwh\)神仙在超越,我打了个\(treap\)的板子就 ...

  8. BZOJ 3195 [Jxoi2012]奇怪的道路 | 状压DP

    传送门 BZOJ 3195 题解 这是一道画风正常的状压DP题. 可以想到,\(dp[i][j][k]\)表示到第\(i\)个点.已经连了\(j\)条边,当前\([i - K, i]\)区间内的点的度 ...

  9. luogu1941 [NOIp2014]飞扬的小鸟 (dp)

    设f[i][j]为到达(i,j)这个位置的最小操作数 就有$f[i][j]=min\{f[i-1][j+Y[i-1]],f[i-1][j-X[i-1]*k]+k\}$ 然后考虑优化一下转移: 对于一系 ...

  10. Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)

    Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...