Java并发编程的艺术学习笔记(三) Java内存模型(五)

3.5 锁的内存语义

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

Java并发编程的艺术学习笔记(三) Java内存模型(五)_第1张图片

每一个箭头链接的两个节点,代表了一个happens-before关系。黑色箭头表示 程序顺序规则;橙色箭头表示监视器锁规则;蓝色箭头表示组合这些规则后提供的happensbefore保证。


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

对比锁释放-获取的内存语义与volatile写-读的内存语义可以看出:锁释放与volatile写有 相同的内存语义;锁获取与volatile读有相同的内存语义。
下面对锁释放和锁获取的内存语义做个总结。
·线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息。
·线程B获取一个锁,实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息。
·线程A释放锁,随后线程B获取这个锁,这个过程实质上是线程A通过主内存向线程B发送消息。

3.5.3 锁内存语义的实现

公平锁在释放锁的最后写volatile变量state,在获取锁时首先读这个volatile变量

非公平锁释放和公平锁完全一样。获取调用本地方法。程序通过当前处理器类型来决定是否添加lock前缀,多处理器就添加,单处理器就省略。

现在对公平锁和非公平锁的内存语义做个总结。
·公平锁和非公平锁释放时,最后都要写一个volatile变量state。
·公平锁获取时,首先会去读volatile变量。
·非公平锁获取时,首先会用CAS更新volatile变量,这个操作同时具有volatile读和volatile写的内存语义。
从本文对ReentrantLock的分析可以看出,锁释放-获取的内存语义的实现至少有下面两种方式。
1)利用volatile变量的写-读所具有的内存语义。
2)利用CAS所附带的volatile读和volatile写的内存语义。

3.5.4 concurrent包的实现

Java并发编程的艺术学习笔记(三) Java内存模型(五)_第2张图片

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


 

你可能感兴趣的:(并发编程,Java)