zoukankan      html  css  js  c++  java
  • JVM锁说明

          以前Synchronised关键字加锁效率问题,经常受到吐槽。后来java的开发团队进行了优化,引入了偏向锁、自旋锁、轻量锁,性能有了很大的提升。下面我们来分析下这里面的过程和原理。
     
         最初阶段,我们的代码段或者方法加syncronized关键字,如下:
    syncronized(object) {
               // do something 
          }

    执行这段代码时,其实相当于,在这段代码前面加了monitorenter指令;后面加了monitorexit指令。如下:

     
     monitorenter
      // do something
      monitorexit
     
     这两指令都得和操作系统连接,相对来说是比较重的,比较耗时的。
     
    但是,在代码里加synchronised 关键字时,只是全面考虑,很多情况只有一个线程在执行,如果在有这种情况下,就有些浪费了;另外,有时,即使多线程访问,他的等待时间是很短的,比monitorenter相关指令还轻,这也是可想办法优化的。
     
    在叙述相关优化锁之前,我们先说下java 对象头部分的 Mark Word。在32位虚拟机上,他的长度是32位;在64位虚拟机上,他的长度是64位。
     
    普通情况下,Mark Word的格式如下:
    hash:25 ------------>| age:4    | biased_lock:1 lock:2
     
    最后部分2个比特,是固定的,表示对象锁的状况
    01 表示无锁,或者偏向锁; 00表示轻量级锁;10表示重量级锁
     
    第三部分是标识是否偏向锁。当最后部分为01时,第三部分为0表示普通无锁对象,第三部分为1表示偏向锁;最后部分为其他值,第三部分不存在。
     
    age表示分代年龄;hash表示对象hash值。
     
    普通无锁:对象hash:25 ------------>| age:4    | 0 | 01
    偏向锁:偏向锁的线程和时间戳:25 ------------>| age:4    | 1 | 01
    轻量锁:指向栈中锁记录的指针:30  | 00
    重量锁:指向互斥量(重量级锁)的指针:30 | 10
     
    java1.6之后,对象有4中状态:无锁态,偏向锁态,轻量锁态,重量锁态。
     
    java程序执行,没有遇到同步块时,都是无锁态。Mark Word如上普通无锁的情况。
     
    遇到同步块之后,Mark Word从普通无锁变成偏向锁的情况,通过CAS加锁。如果是相同线程在次进入,不受影响。执行完成,CAS解锁,Mark Word又变成普通无锁的情况。
     
    如果在偏向锁中,遇到锁竞争的情况。先线程停止,通过CAS锁升级到轻量锁,成功的一方继续执行,另一方开始自旋操作。待他完了继续执行。这里的自旋有个智能学习的策略。假设每个同步块的初始自旋次数是20次,A同步块的线程自旋时,每次很小的自旋次数就获得了执行时间,那后面他的自旋信用会很高,会超过20次往上升;B同步块的线程自旋时,每次都需要很大的自旋次数才能获得执行时间,后面就会把他的自旋次数从20往下降或者不给自旋机会。
     
    当然,自旋失败后,锁得再次升级,通过CAS操作从轻量锁升级到重量锁,这就回到一开始的moniterenter指令和moniterexit指令了。
     
    jvm还有其他一些锁的优化措施。
     
    锁清除:在某些情况下,同步块中的代码不可能被其他线程访问修改的时候,这时候的锁是可以清除的。
    锁粗化:在一些代码中,会频繁的加锁,加锁,加锁;当然,有时并不是程序员这么编写的,因为我们的jdk api中也会加些锁操作。我们得频繁的做互斥操作,可以把几个同步块合并成一个同步块来优化执行。
     
     
     
  • 相关阅读:
    YC创始人格雷厄姆为何不喜欢大学生创业?
    在创业的道路上,让公司生存下去是做重要的!
    农村90后李传帅的创业故事
    创业公司的出头之日在哪里?
    创业者不能盲目的跟风,不然结局很凄凉
    小程序到底适不适合创业者
    共享经济的涨潮与退潮就在一瞬间
    互联网行业进入焦虑时代,如何才能做到攻守有道?
    88
    JZOJ.5331【NOIP2017模拟8.23】壕游戏
  • 原文地址:https://www.cnblogs.com/sten/p/5651484.html
Copyright © 2011-2022 走看看