java重量锁教程简介
周舟 2017年04月08日发布
-
本文主要是分享java重量锁的教程,让程序员能够对java重量锁有一个详细的了解。
synchronized实际上应该算是一种java内置锁,大部分实现依赖jvm虚拟机的实现。所以在使用上,synchronized对java语言开发者来说更为友好。大部分的开发者不用关心synchronized的内部实现是怎样的。只需要按照java语法规范对临界区进行加锁即可。
在1.6版本之前,synchronized被称为重量级锁,其实现机制是这样的。
JVM会为每一个被synchronized关联为锁的对象(Object)关联一个对象监视器(Monitor),monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处, JVM要保证每个monitorenter必须有对应的monitorexit与之配对。
而每个monitor对象都包含了如下几个部分,cxq(Contention List),EntryList,Wait Set。
1,cxq(Contention List) FILO竞争队列,应对多线程竞争锁的时候,使用CAS操作替换队列头部。
2,EntryList cxq中的合适线程可以被放入EntryList,Wait Set中的线程被notify()之后,也会放入EntryList中,准备竞争锁。
3,Wait Set 线程被wait()后,将会被放入Wait Set中。
竞争锁的线程都会先通过互斥同步或CAS操作进入cxq,队首的对象会进入到EntryList中,进行tryLock操作。成功则获得当前锁。如果失败,则被调用wait()阻塞,进入到Wait Set中。当进入Wait Set中的线程被notify()后,线程将进入到EntryList中。如果是被notifyAll()线程将重新通过互斥同步或CAS操作进入到cxq中。
通过上述的描述,大家可以发现java实现的内置锁在多线程并发过程中会涉及到大量的互斥同步或CAS操作。 当一个线程在进入一段临界区的时候,实际场景是没有线程与该线程进行竞争,这个时候进行互斥同步或CAS操作也是浪费的。
所以这个时期的synchronized被称为重量级锁,在java1.6中通过增加偏向锁、轻量级锁来解决上述的问题。