JDK25的ScopedValue是什么?为什么可以替代ThreadLocal?

典型回答 **ScopedValue**** 是 Java 25 中引入的一个API(JEP 429)**,它是一种能够在特定作用域内共享不可变数据的新机制,主要用于在线程内和跨线程之间安全、高效地传递数据。 它的核心思想是 “作用域” (Scope)。一个 ScopedValue 的值被绑定到一个动态定义的作用域上。一旦执行流程退出这个作用域,该绑定就会被自动撤销。这个作用域通常由 runWhere(ScopedValue, value, Runnable) 方法来定义。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 1. 声明一个 ScopedValue(通常为 static final) final static ScopedValue<String> USER_CONTEXT = ScopedValue.newInstance(); // 2. 在某个作用域内“绑定”一个值,并运行代码 ScopedValue.runWhere(USER_CONTEXT, "Hollis", () -> { // 在这个 Lambda(作用域)内,USER_CONTEXT 的值是 "Hollis" methodThatReadsUserContext(); }); // 3. 在作用域内的任何地方读取值 void methodThatReadsUserContext() { String user = USER_CONTEXT.get(); // 获取到 "Hollis" System.out.println("User is: " + user); } // 退出 runWhere 的代码块后,USER_CONTEXT 与 "Hollis" 的绑定自动失效 ScopedValue 被设计用来解决 ThreadLocal 的一些长期存在的问题的,相比 ThreadLocal 他有几个优势: ...

March 22, 2026 · 1 min · santu

new Thread().start() 创建一个线程时,操作系统层面发生了什么?

题外话:这个问题是今年秋招作业帮出过的一道题,面试官问的还挺有水平的,其实这个问题考察的就是虚拟线程相关的问题,或者说是虚拟线程出来之前的平台线程的实现原理。因为涉及到一点操作系统底层了,所以不好回答。据说完全答对的几乎没有。 典型回答 new Thread().start()这个方法创建并启动线程的话,用的是平台线程,Java早期(JDK 21之前的线程,以及JDK 21之后不用虚拟线程的时候)的线程的是实现是靠操作系统内核线程来实现的,并且Java线程和OS内核线程之间是一对一的关系。 ✅JDK21 中的虚拟线程是怎么回事? 所以,操作系统层面,**new Thread()**主要是进行OS线程的创建,主要分以下四步: 分配内核线程 内核为新线程创建线程控制块(TCB),包含: 线程 ID(TID) 寄存器状态(PC、SP 等) 调度优先级 所属进程(共享地址空间、文件描述符等) 分配栈空间 用户态栈:默认大小由 JVM 控制(可通过 -Xss 设置,如 -Xss1m)。 例如:Linux 上默认可能是 1MB(但实际是虚拟内存,按需分配物理页)。 内核栈:每个线程在内核中也有自己的栈(通常 8–16KB),用于系统调用。 设置初始上下文 程序计数器(PC)指向 thread_entry_point(JVM 的 C 入口函数)。 栈指针(SP)指向新分配的用户栈顶部。 加入调度器就绪队列 线程状态变为 RUNNABLE(可运行)。 由操作系统的调度器(如 Linux 的 CFS)决定何时在 CPU 上执行。 而**.start**方法的调用,则是线程的真正执行了: 新线程拿到CPU时间片 执行 <font style="color:rgb(17, 17, 51);background-color:rgba(175, 184, 193, 0.2);">thread_entry_point</font> → 初始化 JNI → 调用 <font style="color:rgb(17, 17, 51);background-color:rgba(175, 184, 193, 0.2);">Thread.run()</font> → 最终执行你传入的 <font style="color:rgb(17, 17, 51);background-color:rgba(175, 184, 193, 0.2);">Runnable.run()</font>。

March 22, 2026 · 1 min · santu

留言给博主