美文网首页
synchronized 的实现

synchronized 的实现

作者: Wi1ls努力努力再努力 | 来源:发表于2019-05-05 16:42 被阅读0次

    在 Hotspot 虚拟机中,Java 对象头包含_mark 和_klass(继承自 OopDesc),其中synchronized 用的锁就是保存在_mark 中的。
    synchronized 中锁的状态分为无锁/偏向锁/轻量级锁/重量级锁 四种状态。同时这几个状态随着竞争情况逐渐升级。并且锁可以升级但是无法降级。
    同时编译器会清除一些使用了同步,但是代码块内却没有涉及同步数据的锁。


    Java对象头Mark Word
    • 无锁
      • 不锁定资源,所有线程都可以访问并且修改资源,但是只有一个线程可以修改成功。特点是修改操作在循环体内,如 CAS 操作。
    • 偏向锁 Biased Lock
      • 大部分情况下,锁不存在多线程竞争,并且总是由同一个线程多次获得。于是便引入了偏向锁。
      • 当锁对象第一次被线程获得时,会将对象头的标志位设置为01,即偏向模式。同时 CAS操作尝试将获取锁的线程 ID 记录在 Mark Word。若 CAS 成功,则表示获取锁成功。当当前线程再次去获得锁或者退出同步的时候,无需进行 CAS,只要简单的检测下Mark Wrod 记录的线程 ID 是否是当前 ID 即可。
      • 当其他线程尝试去获得偏向锁时,发现锁的线程 ID 不是当前线程,即发生了竞争。此时已经获得偏向锁的线程会释放锁(达到一个全局安全点 safe point)。撤销偏向锁后,会根据拥有偏向锁的线程状态将_mark 设置为无锁状态或者变成轻量级锁(标志设置为 00)。


        锁的状态转换以及 Mark Word

    实验来看看偏向锁下的 Mark Word 是什么样子的,JDB+HDSB
    jsd 附带参数 -XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0表示开启偏向锁

    public class Main {
      public static void main(String[] args) {
        Main main = new Main();
        main.addString("sss");
      }
    
      private List<String> list = new ArrayList<>();
    
      public void addString(String s) {
        synchronized (this) {
          list.add(s);
        }
      }
    
    }
    

    运行 jdb,在 list.add(s);加上断点


    轻量级锁

    相关文章

      网友评论

          本文标题:synchronized 的实现

          本文链接:https://www.haomeiwen.com/subject/payhoqtx.html