锁的释放-获取建立的happens before关系
锁是Java并发编程中最重要的同步机制,锁除了了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息
public class MonitorExample {
int a = 0;
public synchronized void writer() {// 1
a++;// 2
}// 3
public synchronized void reader() {// 4
int i = a;// 5
}// 6
}
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
上图表示线程A释放锁之后,随后线程B获取同一个锁,也就2 happens before 5 。
锁释放和获取的内存语义
当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中
锁释放示意图
而线程B获取锁,JMM会把其对应内存置为无效,从而使被监视器保护的临界区代码必须要从主内存去读取共享变量
锁获取示意图
锁的内存语义总结:
1、线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发送了(线程A对共享变量做了修改的)消息
2、线程B获取一个锁,实质上是线程B接收了之前线程A发的(在释放锁之前对共享变量做了修改的)消息
3、线程A释放锁,随后线程B获取锁,这个过程实质上级是线程A通过主内存向线程B发送消息