美文网首页
Java 锁总结 (未完待续)

Java 锁总结 (未完待续)

作者: 兴厚 | 来源:发表于2020-04-07 21:10 被阅读0次

    本文持续更新,目前 JDK版本为 8

    HotSpot 基础信息(x86 64位)

    1. 对象结构 (参考资料: https://weekly-geekly.github.io/articles/447848/index.html

      在 Hotspot 中一个对象由四部分数据组成。

      ① mark word (对象加锁后状态的变化就表现在这里面,下面的结构不确定)

      1. identity_hashcode 值 31bit
      2. GC 分代年龄 4 bit
      3. biased_lock 1bit lock 2bit

      ② class pointer (类型指针)

      1. 指向类的metadata

      ③ 实例数据

      ④ padding (位填充,使得对象的大小为8 byte的倍数)

      ​ 1. 按8字节对齐

      数组有一个额外的32bit 来描述它的长度信息,下面引用自 Hotspot jdk8源码 markOop.hpp

    //  32 bits:
    //  --------
    //             hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
    //             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
    //             size:32 ------------------------------------------>| (CMS free block)
    //             PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
    //
    //  64 bits:
    //  --------
    //  unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)
    //  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
    //  PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
    //  size:64 ----------------------------------------------------->| (CMS free block)
    

    锁基础信息

    1. 锁分类

      1. 无锁,表现在对象的 markword 标记位的后三位,最后两位锁标志位为 01,倒数第三位偏向锁位为0
      2. 偏向锁,只偏向于某个线程的锁即为偏向锁。 最后两位锁标志位为 01,倒数第三位偏向锁位为0。 当有2个线程及以上竞争时就会升级为轻量锁。在 Hotspot 中为默认开启(UseBiasedLocking)。但会有4秒延迟(BiasedLockingStartupDelay).
      3. 轻量锁, 大于两个线程小于系统cpu核数/2的线程数竞争会处在这个阶段,cas 实现,锁标志位 00
      4. 重量锁,会调用 os 的锁机制来实现,所以效率比较低下,锁标志位 10
    2. 锁升级过程

      ​ Hotspot启动默认开启了偏向锁开关,虽然偏向锁只对单个线程有用,看起来和无锁差不多,但是由于jvm的实现大部分都包含有同步的方法,在日常使用过程中,这些方法只会被同一个线程使用,就不需要重量级锁的实现了,所以加了这个偏向锁。默认开启了4秒延迟。这是由于应用场景的约束,

    Synchronized

    使用方法: 锁住这个对象的指定代码块,同一时间只能有一个线程执行这个代码块中的方法。这并不意味这同时只能有一个线程进入这个代码块,而是执行这个代码块的方法。

    // DCL 经典代码, 和 volatile 配合使用更安全(静止指令重排序)
    example-1:
    if (multiDemo == null) {
        synchronized (MultiDemo.class) {
            if (multiDemo == null) {  // 如果不加这个判断,实现不了单例。
                multiDemo = new MultiDemo();
            }
        }
    }
    example-2:
    
    

    代码分析:

    相关文章

      网友评论

          本文标题:Java 锁总结 (未完待续)

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