JVM 偏向锁 4 秒延迟:从源码动机到 JEP-374 废弃全链路

面试高频考点:偏向锁为什么要延迟启动?启动期到底哪些对象在抢锁?后来为什么整个偏向锁都被删了?

本文所有结论均附 OpenJDK 源码 / JEP 原文出处,不杜撰。


一、一句话结论

BiasedLockingStartupDelay=4000(默认 4 秒)不是"专门针对类加载器对象"的特殊逻辑,而是一个全局时间开关 :JVM 启动后的前 4 秒内,所有新分配对象的 Mark Word 直接是无锁状态(不允许匿名偏向);4 秒到点后,才对当前已加载的所有类未来新分配的对象开放偏向锁能力。

它的唯一目的:规避 JVM 启动阶段大量偏向锁撤销触发的安全点(Safepoint)STW,避免拖慢启动速度


二、HotSpot 源码原始注释(最权威证据)

文件:hotspot/src/share/vm/runtime/biasedLocking.cppBiasedLocking::init() 方法:

cpp 复制代码
void BiasedLocking::init() {
    // If biased locking is enabled, schedule a task to fire a few
    // seconds into the run which turns on biased locking for all
    // currently loaded classes as well as future ones. This is a
    // workaround for startup time regressions due to a large number of
    // safepoints being taken during VM startup for bias revocation.
    // Ideally we would have a lower cost for individual bias revocation
    // and not need a mechanism like this.
    if (UseBiasedLocking) {
        if (BiasedLockingStartupDelay > 0) {
            EnableBiasedLockingTask* task =
                new EnableBiasedLockingTask(BiasedLockingStartupDelay);
            task->enroll();
        } else {
            VM_EnableBiasedLocking op(false);
            VMThread::execute(&op);
        }
    }
}

逐行翻译这段注释的关键信息:

原文 含义
workaround for startup time regressions 这是一个临时补丁,用来解决启动时间回退问题
a large number of safepoints being taken during VM startup for bias revocation 根因是启动阶段大量偏向撤销触发安全点 STW
Ideally we would have a lower cost for individual bias revocation and not need a mechanism like this 理想情况下应该降低单次偏向撤销的开销,就不需要这套机制了

源码自己都承认这是 workaround,不是什么优雅设计。这是面试时可以直接引用的金句。

4 秒到点时具体做了什么?

cpp 复制代码
void VM_EnableBiasedLocking::doit() {
    // 1. 遍历系统字典中所有已加载的类,把它们的 prototype_header 改为偏向模式
    SystemDictionary::classes_do(enable_biased_locking);
    // 2. 标记全局开关,未来新分配的对象也走偏向模式
    _biased_locking_enabled = true;
}

两个动作:

  1. 已加载类 :修改类的 prototype_header(类的原型对象头),之后该类 new 出来的新对象会继承匿名偏向的 Mark Word。
  2. 未来对象:全局开关打开,新分配对象默认带匿名偏向标记。

注意:4 秒前已经分配好的对象,Mark Word 不会被回溯修改,它们终身是无锁状态,不会进入偏向。只有 4 秒之后 new 出来的对象才有资格走偏向锁。


三、启动期到底哪些对象在被多线程抢锁?

3.1 核心判断标准

一个对象会在启动期引发锁竞争,必须同时满足:

  1. 对象在 JVM 启动极早期被创建(落在 0~4 秒窗口内)
  2. 是全局单例(所有线程共享同一个对象,不是每个线程各 new 一个)
  3. 会被多条不同线程交替访问(不是固定一个线程独占)

3.2 典型对象清单

① 各类基础类的 Xxx.class 对象(最典型)

java.lang.Integer 为例:

  • 谁在抢:主线程、JIT 编译线程、Finalizer 线程、ReferenceHandler 线程,几乎同时第一次访问 Integer
  • 抢的是什么 :JVM 规范规定,每个类 C 有一个唯一的初始化锁 LC,HotSpot 的实现就是用 Class 对象本身当锁
  • 为什么必须加锁<clinit>() 静态初始化方法全局只能执行一次,多线程同时触发类初始化时,必须用锁互斥

JLS 12.4.2 原文(类初始化详细过程第一步):

"Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC."

伪代码等价:

java 复制代码
synchronized (Integer.class) {       // 多个线程抢同一个 Class 对象锁
    if (Integer 已初始化完成) return;
    Integer.<clinit>();              // 只跑一次:初始化 IntegerCache 缓存池
    标记初始化完成;
}

关键细节 :每个类的 <clinit> 竞争只发生一次(类初始化完成后就不再抢了),但启动阶段有几十上百个 JDK 基础类(Integer、Long、Boolean、Double、String、Math、ArrayList、HashMap......)扎堆并发加载,每个类各自发生一次瞬时竞争,积少成多。

同样的逻辑适用于:Long.classBoolean.classString.classMath.classArrayList.classHashMap.class 等所有启动期被多线程首次访问的类。

② ClassLoadingLock 对象(JDK 7+)

ClassLoader.loadClass() 不再对 this 加锁,而是调用 getClassLoadingLock(className),内部维护一张哈希表:key 是类全限定名,value 是 new Object() 锁对象。

  • 谁在抢:多个线程同时加载同一个类名时,拿到同一个锁对象
  • 特征:对象在类加载过程中创建,落在启动窗口内
③ JVM 内部全局锁对象(C++ 层,映射到 Java 监视器)
  • StringTable / SymbolTable 内部锁:启动期大量字符串常量 intern、符号插入,多线程并发操作哈希表
  • 引用队列锁java.lang.ref 包静态初始化创建的锁对象,协调应用线程、Finalizer 线程、ReferenceHandler 线程
  • SystemDictionary 内部锁:类名到 Class 对象的注册表,多线程并发查找插入
④ 应用代码早期创建的 static 全局锁对象(容易被忽略)
java 复制代码
public class App {
    // 诞生于 0~4 秒窗口,哪怕是业务代码 new 的,同样禁止匿名偏向
    public static final Object GLOBAL_LOCK = new Object();
}

机制只看对象分配时间,不看对象属于 JDK 内部还是业务代码。这一点是面试常考的认知误区。

3.3 这些对象的共同特征总结

复制代码
┌─────────────────────────────────────────────────┐
│           启动期高竞争锁对象的共同特征              │
├─────────────────────────────────────────────────┤
│  1. 创建时间极早 → 落在 0~4s 偏向锁关闭窗口内      │
│  2. 全局单例    → 所有线程共享同一个对象           │
│  3. 多线程交替  → 不是固定一个线程长期持有         │
│  4. 线程来源杂  → 主线程 + JIT + 守护线程都来碰    │
└─────────────────────────────────────────────────┘

四、如果没有 4 秒延迟会发生什么?(完整因果链)

假设设置 -XX:BiasedLockingStartupDelay=0,拿 Integer.class 走一遍:
JVM安全点 Integer.class对象 线程B(JIT线程) 线程A(主线程) JVM安全点 Integer.class对象 线程B(JIT线程) 线程A(主线程) #mermaid-svg-kkszQwgYeSkDvFp3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kkszQwgYeSkDvFp3 .error-icon{fill:#552222;}#mermaid-svg-kkszQwgYeSkDvFp3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kkszQwgYeSkDvFp3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kkszQwgYeSkDvFp3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kkszQwgYeSkDvFp3 .marker.cross{stroke:#333333;}#mermaid-svg-kkszQwgYeSkDvFp3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kkszQwgYeSkDvFp3 p{margin:0;}#mermaid-svg-kkszQwgYeSkDvFp3 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kkszQwgYeSkDvFp3 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kkszQwgYeSkDvFp3 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-kkszQwgYeSkDvFp3 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-kkszQwgYeSkDvFp3 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-kkszQwgYeSkDvFp3 .sequenceNumber{fill:white;}#mermaid-svg-kkszQwgYeSkDvFp3 #sequencenumber{fill:#333;}#mermaid-svg-kkszQwgYeSkDvFp3 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-kkszQwgYeSkDvFp3 .messageText{fill:#333;stroke:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kkszQwgYeSkDvFp3 .labelText,#mermaid-svg-kkszQwgYeSkDvFp3 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .loopText,#mermaid-svg-kkszQwgYeSkDvFp3 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kkszQwgYeSkDvFp3 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-kkszQwgYeSkDvFp3 .noteText,#mermaid-svg-kkszQwgYeSkDvFp3 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-kkszQwgYeSkDvFp3 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kkszQwgYeSkDvFp3 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kkszQwgYeSkDvFp3 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kkszQwgYeSkDvFp3 .actorPopupMenu{position:absolute;}#mermaid-svg-kkszQwgYeSkDvFp3 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-kkszQwgYeSkDvFp3 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kkszQwgYeSkDvFp3 .actor-man circle,#mermaid-svg-kkszQwgYeSkDvFp3 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-kkszQwgYeSkDvFp3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 对象分配,Mark Word = 匿名偏向(101) Mark Word = 已偏向A(101+线程A指针) 发现锁已偏向A,A已退出同步块 Mark Word 退回无锁(001) 抢锁,CAS成功,对象偏向线程A执行<clinit>,释放锁来抢同一把锁触发全局安全点STW,暂停所有Java线程遍历线程栈,撤销偏向标记升级轻量级锁CAS抢轻量级锁成功

每一次"别的线程来抢一个已被偏向的对象",都要走一次全局安全点 STW。启动期几十个类各来一次,STW 次数爆炸,启动时间显著拉长。

这就是源码注释说的 "a large number of safepoints being taken during VM startup for bias revocation"。


五、4 秒延迟的本质:不是识别对象,是按时间一刀切

#mermaid-svg-TucgDjx8fBn9u0Pn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TucgDjx8fBn9u0Pn .error-icon{fill:#552222;}#mermaid-svg-TucgDjx8fBn9u0Pn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TucgDjx8fBn9u0Pn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TucgDjx8fBn9u0Pn .marker.cross{stroke:#333333;}#mermaid-svg-TucgDjx8fBn9u0Pn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TucgDjx8fBn9u0Pn p{margin:0;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge{stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .section--1 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section--1 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section--1 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section--1 text{fill:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth--1{stroke-width:17;}#mermaid-svg-TucgDjx8fBn9u0Pn .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-0 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-0 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-0 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-0 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-0{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-0{stroke-width:14;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-1 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-1 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-1 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-1 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-1{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-1{stroke-width:11;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-2 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-2 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-2 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-2 text{fill:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-2{stroke-width:8;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-3 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-3 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-3 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-3 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-3{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-3{stroke-width:5;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-4 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-4 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-4 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-4 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-4{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-4{stroke-width:2;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-5 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-5 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-5 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-5 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-5{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-5{stroke-width:-1;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-6 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-6 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-6 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-6 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-6{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-6{stroke-width:-4;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-7 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-7 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-7 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-7 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-7{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-7{stroke-width:-7;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-8 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-8 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-8 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-8 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-8{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-8{stroke-width:-10;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-9 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-9 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-9 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-9 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-9{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-9{stroke-width:-13;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-10 rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-10 path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-10 circle,#mermaid-svg-TucgDjx8fBn9u0Pn .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-10 text{fill:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .node-icon-10{font-size:40px;color:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .edge-depth-10{stroke-width:-16;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-TucgDjx8fBn9u0Pn .lineWrapper line{stroke:black;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled circle,#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:lightgray;}#mermaid-svg-TucgDjx8fBn9u0Pn .disabled text{fill:#efefef;}#mermaid-svg-TucgDjx8fBn9u0Pn .section-root rect,#mermaid-svg-TucgDjx8fBn9u0Pn .section-root path,#mermaid-svg-TucgDjx8fBn9u0Pn .section-root circle{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-TucgDjx8fBn9u0Pn .section-root text{fill:#ffffff;}#mermaid-svg-TucgDjx8fBn9u0Pn .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-TucgDjx8fBn9u0Pn .edge{fill:none;}#mermaid-svg-TucgDjx8fBn9u0Pn .eventWrapper{filter:brightness(120%);}#mermaid-svg-TucgDjx8fBn9u0Pn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 0s JVM启动 新对象 Mark Word =无锁(001) 禁止匿名偏向 4s EnableBiasedLockingTask触发 已加载类的prototype_header改为偏向模式 全局开关_biased_locking_enabled= true >4s 新对象 Mark Word =匿名偏向(101) 允许走偏向锁逻辑 对象分配时间 vs 偏向锁能力

两个常见误区

误区 真相
4 秒后,老对象也会自动变成可偏向 ❌ 不会。只有 4 秒后 new 出来的对象才有匿名偏向标记,老对象终身无锁
4 秒延迟是专门识别、过滤 JVM 内部对象 ❌ 没有特殊识别逻辑,纯粹按对象分配时间一刀切。业务代码在启动前 4 秒 new 的对象同样不能偏向

六、后来为什么把整个偏向锁都删了?(JEP-374)

6.1 版本时间线

版本 事件 出处
JDK 6 引入偏向锁,默认开启 ---
JDK 15(2020.09) 默认关闭偏向锁,废弃所有相关参数 JEP-374
JDK 18 彻底删除偏向锁代码,参数不再识别(obsolete) JDK-8256425

原本计划 JDK 16 删除,后延期到 JDK 18(JDK-8256253)。

被废弃的参数清单(JEP-374 原文列出):

  • Product:BiasedLockingStartupDelayBiasedLockingBulkRebiasThresholdBiasedLockingBulkRevokeThresholdBiasedLockingDecayTimeUseOptoBiasInlining
  • Diagnostic:PrintBiasedLockingStatisticsPrintPreciseBiasedLockingStatistics

6.2 废弃的四大原因(JEP-374 Motivation 原文归纳)

① 硬件变化:CAS 原子指令成本大幅下降

JEP 原文:"The cost of executing atomic instructions has decreased on modern processors since the introduction of biased locking into HotSpot."

偏向锁诞生的初衷是省去 CAS 原子操作。当年 CAS 很贵,今天 CAS 已经很便宜,偏向锁省下来的那点开销微不足道。

② 受益场景萎缩:只有老应用还在吃红利

JEP 原文:"Many applications that benefited from biased locking are older, legacy applications that use the early Java collection APIs, which synchronize on every access (e.g., Hashtable and Vector)."

  • 老应用:HashtableVector------每次访问都 synchronized,单线程场景下偏向锁收益大
  • 现代应用:HashMapArrayList(Java 1.2 引入,单线程无锁)或 ConcurrentHashMap(Java 5 引入,高并发),本身就减少了不必要的 synchronized
③ 线程池架构的应用,关闭偏向锁反而更快

JEP 原文:"applications built around a thread-pool queue and worker threads generally perform better with biased locking disabled. (SPECjbb2015 was designed that way)"

现代微服务基本都是"线程池 + Worker 线程"架构。同一个锁对象在不同 Worker 线程之间频繁换手,一旦竞争就触发偏向撤销 STW,P99 延迟恶化。SPECjbb2015 基准测试就是关闭偏向锁后性能更好。

④ 维护成本太高,阻碍 JVM 演进

JEP 原文:"Biased locking introduced a lot of complex code into the synchronization subsystem and is invasive to other HotSpot components as well. This complexity is a barrier to understanding various parts of the code and an impediment to making significant design changes."

偏向锁的状态机极其复杂:匿名偏向、已偏向、批量重偏向(bulk rebias)、批量撤销(bulk revoke)、epoch 机制、线程死亡处理......代码侵入线程、GC、解释器、JIT 各个模块。Project Loom(虚拟线程)要改造同步子系统时,偏向锁是巨大障碍。

6.3 关键澄清:不是启动期锁竞争被解决了

误区:JDK 优化了,启动期不再多线程初始化基础类,所以不需要 4 秒延迟了。

真相 :类加载并发逻辑、<clinit> 锁机制几乎没有改动。启动期 Integer.class 等对象依旧会被多线程争抢,只是现在直接走轻量级锁 CAS,不再有"偏向→撤销→STW"这条路径,自然也就不需要 4 秒这个补丁了。


七、全链路因果图(面试默写版)

#mermaid-svg-Y2ibSJGbjSjw8GRS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Y2ibSJGbjSjw8GRS .error-icon{fill:#552222;}#mermaid-svg-Y2ibSJGbjSjw8GRS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Y2ibSJGbjSjw8GRS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .marker.cross{stroke:#333333;}#mermaid-svg-Y2ibSJGbjSjw8GRS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Y2ibSJGbjSjw8GRS p{margin:0;}#mermaid-svg-Y2ibSJGbjSjw8GRS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .cluster-label text{fill:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .cluster-label span{color:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .cluster-label span p{background-color:transparent;}#mermaid-svg-Y2ibSJGbjSjw8GRS .label text,#mermaid-svg-Y2ibSJGbjSjw8GRS span{fill:#333;color:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .node rect,#mermaid-svg-Y2ibSJGbjSjw8GRS .node circle,#mermaid-svg-Y2ibSJGbjSjw8GRS .node ellipse,#mermaid-svg-Y2ibSJGbjSjw8GRS .node polygon,#mermaid-svg-Y2ibSJGbjSjw8GRS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .rough-node .label text,#mermaid-svg-Y2ibSJGbjSjw8GRS .node .label text,#mermaid-svg-Y2ibSJGbjSjw8GRS .image-shape .label,#mermaid-svg-Y2ibSJGbjSjw8GRS .icon-shape .label{text-anchor:middle;}#mermaid-svg-Y2ibSJGbjSjw8GRS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .rough-node .label,#mermaid-svg-Y2ibSJGbjSjw8GRS .node .label,#mermaid-svg-Y2ibSJGbjSjw8GRS .image-shape .label,#mermaid-svg-Y2ibSJGbjSjw8GRS .icon-shape .label{text-align:center;}#mermaid-svg-Y2ibSJGbjSjw8GRS .node.clickable{cursor:pointer;}#mermaid-svg-Y2ibSJGbjSjw8GRS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .arrowheadPath{fill:#333333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Y2ibSJGbjSjw8GRS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Y2ibSJGbjSjw8GRS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Y2ibSJGbjSjw8GRS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Y2ibSJGbjSjw8GRS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .cluster text{fill:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS .cluster span{color:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Y2ibSJGbjSjw8GRS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Y2ibSJGbjSjw8GRS rect.text{fill:none;stroke-width:0;}#mermaid-svg-Y2ibSJGbjSjw8GRS .icon-shape,#mermaid-svg-Y2ibSJGbjSjw8GRS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Y2ibSJGbjSjw8GRS .icon-shape p,#mermaid-svg-Y2ibSJGbjSjw8GRS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Y2ibSJGbjSjw8GRS .icon-shape .label rect,#mermaid-svg-Y2ibSJGbjSjw8GRS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Y2ibSJGbjSjw8GRS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Y2ibSJGbjSjw8GRS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Y2ibSJGbjSjw8GRS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} JDK6 引入偏向锁
目的: 单线程反复拿锁时省去CAS
问题: 别的线程来抢已偏向对象时

必须触发全局安全点STW做撤销
JVM启动期: 几十上百个基础类

被主线程+JIT+守护线程并发初始化
每个类的Xxx.class都是全局单例锁对象

多线程争抢 → 大量偏向撤销 → 大量STW
启动时间严重回退
打补丁: BiasedLockingStartupDelay=4000

前4秒新对象禁止匿名偏向
4秒后: 已加载类prototype_header改偏向模式

新对象允许匿名偏向
时代变化
硬件: CAS变便宜了
应用: 线程池架构, 锁频繁换手

偏向撤销STW反而恶化P99
代码: 状态机太复杂, 阻碍虚拟线程等新特性
JEP-374: JDK15默认关闭
JDK18: 彻底删除代码, 参数obsolete
4秒延迟随偏向锁一起消失

启动期竞争直接走轻量级锁CAS


八、面试高频 Q&A

Q1:偏向锁为什么要延迟 4 秒启动?

:不是为了等什么,而是为了避开 JVM 启动阶段的高竞争期 。启动期大量基础类的 Class 对象、ClassLoadingLock、JVM 内部全局锁对象会被主线程、JIT 线程、守护线程并发争抢。如果一启动就开启偏向锁,这些对象会频繁经历"偏向→被别的线程抢→安全点 STW 撤销"的循环,大量 STW 拖慢启动。所以前 4 秒新对象直接无锁,4 秒后启动期高竞争基本结束,再开放偏向锁。

Q2:4 秒延迟是专门针对类加载器对象吗?

:不是。它是按对象分配时间的全局一刀切开关,不识别对象类型。类加载器相关锁对象确实是启动期高竞争对象的典型代表,但业务代码在前 4 秒 new 的对象同样被禁止偏向。

Q3:4 秒后,之前创建的对象会变成可偏向吗?

:不会。4 秒到点时只做两件事:修改已加载类的 prototype_header、打开全局开关。已经分配好的对象 Mark Word 不会被回溯修改,它们终身是无锁状态。只有 4 秒之后 new 出来的对象才有匿名偏向标记。

Q4:偏向锁撤销为什么需要安全点 STW?

:撤销偏向时需要遍历所有线程的栈,找到并修改那些正在使用该偏向锁的栈帧中的锁记录(确保递归锁等场景的一致性)。遍历线程栈必须在所有线程都暂停的安全点才能安全进行,所以是全局 STW。这也是偏向锁撤销代价高的根本原因。

Q5:JDK 15 之后偏向锁怎么了?

:JDK 15 通过 JEP-374 默认关闭偏向锁并废弃相关参数;JDK 18 彻底删除偏向锁代码,UseBiasedLockingBiasedLockingStartupDelay 等参数不再被识别。原因是现代 CPU 的 CAS 开销降低、线程池架构下偏向锁反而制造延迟抖动、代码复杂度阻碍虚拟线程等新特性演进。

Q6:启动期 Integer.class 的锁竞争会持续很久吗?

:不会。每个类的 <clinit> 只执行一次,初始化完成后其他线程直接返回,不再争抢。但启动期有几十上百个基础类扎堆并发初始化,每个类瞬时竞争一次,累积起来的偏向撤销 STW 次数就很可观了。


九、参考来源

  1. OpenJDK 源码:hotspot/src/share/vm/runtime/biasedLocking.cpp --- BiasedLocking::init() 原始注释
  2. JEP 374: Deprecate and Disable Biased Locking --- http://openjdk.org/jeps/374
  3. JDK-8256425: Obsolete Biased Locking in JDK 18 --- https://bugs.openjdk.org/browse/JDK-8256425
  4. JLS 12.4.2 Detailed Initialization Procedure --- 类初始化锁 LC 规范
  5. OpenJDK Wiki: Biased-locking Synchronization --- BiasedLockingStartupDelay 参数说明
相关推荐
孙克旭_1 小时前
JVM 入门详解:JVM、JRE、JDK 区别,JVM 基础结构梳理
java·开发语言·jvm
随遇而安zx1 小时前
【地基篇】---JVM 内存结构知识点(Java 8 运行时数据区深度解析)
java·开发语言·jvm
恒拓高科WorkPlus3 小时前
企业如何搭建安全内部通讯平台|企业内部通讯平台怎么选才更安全?
jvm·数据库·安全
随遇而安zx5 小时前
【地基篇】---JVM 类加载 源码解析(基于 Java 8)
java·jvm·python
ly76891 天前
JVM 类加载机制:打破双亲委派模型的实践与陷阱
jvm·热部署·spi·类加载器·双亲委派
随遇而安zx1 天前
【地基篇】---Java 8 JVM 知识大纲
java·开发语言·jvm
liangbo71 天前
01-JVM 内存模型全景
java·jvm
ly76891 天前
JVM 内存屏障与可见性:从 volatile 到 JSR-133 的底层实现
jvm·jit·volatile·内存屏障·jmm·jsr-133
晊晌_h2 天前
嵌入式从0到精通——线程
java·开发语言·jvm