惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
Jina AI
Jina AI
The Cloudflare Blog
V
Visual Studio Blog
博客园_首页
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
博客园 - Franky

博客园 - 幽州散人

SQL优化案例 主线任务和使命 温州3日之旅 CompletableFuture + 异步Servlet:同步的姿势、异步的效果 Snowflake雪花算法与发号器的应用 windows Java 幽灵转发壳进程 也谈MySQL limit offset深翻页问题 SHOW SESSION STATUS 与 Handler 变量 MySQL 5.7 Profiles 执行性能分析 MySQL临时表与文件排序 MySQL 5.7 MRR多范围读优化 MySQL 5.7 ICP索引条件下推优化 MySQL符合索引与最左前缀原则 从I/O 的物理成本理解回表和索引覆盖 第4个电瓶以及补漆 Flink原理:并行度与keyGroup桶 什么是数字批发银行 Java虚拟线程(三)实现原理 Java虚拟线程(二) Java虚拟线程(一) 大模型推理层服务化架构 传奇调查员之路:理智值-99,但我必须听懂深渊的语言 js里调用智能合约读/写函数的方法的区别 字节与其16进制字符表示转换的bug Redisson分布式锁 交易心得 DexScreener接口初探 某安全软件跑飞了。。 Ed25519算法签名与验签的Java实现 Tendermint拜占庭容错引擎
synchronized 为啥会让虚拟线程卸载失效
幽州散人 · 2026-09-07 · via 博客园 - 幽州散人

虚拟线程底层如何复用载体线程

虚拟线程实际上是一种封装,把runnable任务封装交给载体线程干活。但向上对程序员提供一套线程api,让程序员像以往使用传统线程一样去使用。
我们知道虚拟线程在底层复用载体线程干活,如果发生阻塞则执行代码(底层实际就是载体线程在执行)调用native方法,jvm就会把虚拟线程从载体线程上yield“卸载”,
(中断载体线程,然后把线程栈中涉及虚拟线程的部分复制到堆中进行保存,载体线程再被调度到其他任务)
载体线程可以去干其他活儿,io就绪结束阻塞之后,代码调用run则重新装载虚拟线程进行执行。(把之前堆中保存的信息恢复到当前线程栈)

synchronized带来的问题

在 Java 24 之前,当虚拟线程进入 synchronized 代码块时,JVM 会将锁的所有者记录为底层的载体线程(Carrier Thread),而不是虚拟线程本身。
这会导致一个问题:当虚拟线程在 synchronized 块内因 I/O 等操作而阻塞时,JVM 本来应该将它“卸载”下来,让载体线程去执行其他任务。但如果这样做,载体线程和虚拟线程的锁所有权关系就会变得混乱。
为了避免这种混乱,JVM 采取了一个简单粗暴的策略:只要虚拟线程在 synchronized 块内,就禁止将其从载体线程上卸载。虚拟线程因此被“钉”在载体线程上,即使它阻塞了,载体线程也无法去执行其他任务,这大大降低了虚拟线程的优势。

Java 24+ 的解决方案 (JEP 491)
为了解决这个问题,JEP 491 修改了 synchronized 的底层实现。其核心思路是让锁的所有权不再依赖于具体的载体线程,从而允许虚拟线程在持有锁的情况下也能被卸载。

1. 锁记录的转移:当虚拟线程被卸载(冻结)时,JVM 会将其持有的锁信息从载体线程的“锁栈”中复制出来,保存到虚拟线程的堆内存栈块(Stack Chunk)中。当虚拟线程被重新挂载(解冻)时,再将锁信息恢复回去。

2. 锁所有者的记录方式:对于重量级锁,JVM 不再记录持有锁的载体线程(JavaThread*),而是直接记录拥有该锁的 java.lang.Thread 的 ID(tid)。这样,锁的所有者就与具体的载体线程解耦了。