偏向锁、轻量级锁、重量级锁

来源:互联网 发布:单片机 光耦 编辑:程序博客网 时间:2024/05/16 07:01
        Java SE1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”的概念,所以在Java SE1.6里锁一共有四种状态:无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,这种策略目的是为了提高获得锁和释放锁的效率。

偏向锁
        Hotspot的作者经过以往的研究发现大多数情况下锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入的偏向锁。当一个线程(下面简称线程A)访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时,只需要对比Mark Word里的线程ID,不需要通过CAS操作来加锁和解锁。

偏向锁撤消和升级轻量级锁
        当遇到别一个线程(下面简称线程B)来访问这个对象,看到共享对象头部标识的线程ID为线程A(偏向锁是不会主动释放的)。线程B会检查线程A是否存活,如果挂了,则将对象变为无锁状态,然后重新偏向线程B,如果依然存活,则检查该对象的使用情况,如果仍然需要持有偏向锁,则偏向锁升级为轻量级锁。如果不存在使用了,则可以将对象恢复成无锁状态,再重新偏向。在这个过程中,线程A会被暂停。

膨胀为重量级锁
        轻量级锁认为竞争存在,但竞争的程度很轻,A、B两个线程对于同一个锁的操作都会错开,或者说稍微等待一下(自旋),另一个线程就会释放锁。
当A、B线程自旋超过一定次数,或者又来了一个线程C来竞争资源,轻量级锁膨胀为重量级锁,重量级锁使竞争锁的线程(未持有锁)都阻塞,防止CPU空转。

三者比较
偏向锁:乐观锁,加锁、解锁不需要额外的消耗,性能接近执行非同步方法。缺点是锁竞争过程中,锁撤消会带来消耗。适用于只有一个线程访问同步块的场景。
轻量级锁:乐观锁,竞争的线程不会阻塞,提高了程序的响应速度。缺点是CAS自旋带来的CPU消耗。适用于追求响应时间,锁占用时间很短的场景。
重量级锁:悲观锁,优点是线程竞争不使用自旋,不消耗CPU资源。缺点是线程阻塞,响应时间缓慢。适用于追求呑吐量,锁占用时间较长的场景。
 
  
 
参考:
http://blog.csdn.net/choukekai/article/details/63688332
http://www.cnblogs.com/wade-luffy/p/5969418.html
阅读全文
0 0
原创粉丝点击