在Java里面,锁除了让临界区互斥外,还可以让释放锁的线程向获取同一个锁的线程发送消息
锁的释放和获取的内存语义
接下来,看一下线程在锁的释放和获取究竟对内存是怎样的操作
锁的释放
当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中
锁的获取
当线程获取锁时,JMM会把该线程对应的本地内存置为无效,从而使得被监视器monitor保护的临界区代码必须从主内存中读取共享变量(前面已经提到过,synchroniced会在字节码上加上monitor与monitor exit)
这两个过程相当于线程A向线程B发送了通信消息,让B读取最新的共享变量
与volatile的读写内存语义比较
通过与前面学习的volatile的读写内存语义比较
-
锁释放与volatile的写语义时相同的(立即更新共享变量到主内存)
-
锁获取与volatile的读语义是相同的(本地内存无效,重新读取)
-
写语义与读语义让线程之间实现了通信
-
锁释放与所获取也让线程之间实现了通信
锁内存语义的实现
锁内存语义的实现其实就是ReentrantLock的底层实现,具体可以回看前面几篇将ReentrantLock的文章