基本用法 ScopedValue对象用jdk.incubator.concurrent包中的ScopedValue类来表示。 使用ScopedValue的第一步是创建ScopedValue对象,通过静态方法newInstance来完成,ScopedValue对象一般声明为static final。 where方法有 3 个参数: ScopedValue 对象 ScopedValue 对象所绑定的值 Runnable或Callable对象,表示ScopedValue对象的作用域 在Runnable或 ScopedValue defines the where(ScopedValue, Object, Runnable) method to set the value of a ScopedValue ScopedValue 定义了 where(ScopedValue, Object, Runnable) 方法,这个方法在一个线程执行 runnable 的 run 方法的有限执行期间内设置 ScopedValue
基本用法 ScopedValue对象用jdk.incubator.concurrent包中的ScopedValue类来表示。 使用ScopedValue的第一步是创建ScopedValue对象,通过静态方法newInstance来完成,ScopedValue对象一般声明为static final。 where方法有 3 个参数: ScopedValue 对象 ScopedValue 对象所绑定的值 Runnable或Callable对象,表示ScopedValue对象的作用域 在Runnable或 ScopedValue defines the where(ScopedValue, Object, Runnable) method to set the value of a ScopedValue ScopedValue 定义了 where(ScopedValue, Object, Runnable) 方法,这个方法在一个线程执行 runnable 的 run 方法的有限执行期间内设置 ScopedValue
2、简单使用package org.example;import java.lang.ScopedValue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ScopeValueDemo { private static final ScopedValue<String > REQUEST_ID = ScopedValue.newInstance(); public static void processRequest(String id) { System.out.println ("--- 线程: " + Thread.currentThread().getName() + " 开始处理 ---"); ScopedValue.where(REQUEST_ID, id 3、ScopedValue和ThreadLocal对比简单总结一下两者的对比:ScopedValue:值是不可变的,天然的线程安全绑定的作用域可以为动态执行范围,该范围代码执行结束会自动清除只是跨线程(
Using ScopedValue instead of ThreadLocal ScopedValue used to called ExtentValue And the second thing : ScopedValue.newInstance(). Live demo: using ScopedValue in a single thread And now, what we are going to do, it to call ScopedValue KEY.get() : "Not bound"); ScopedValue.where(KEY, "A").run(task); ScopedValue.where(KEY, "B"). ThreadLocal与ScopedValue.
Scoped Values API 基于 java.lang 中的一个新类 ScopedValue<T>,它表示将一个值绑定到特定作用域内的一个变量。该值只需编写一次,然后在每个作用域内不可更改。 <Socket> SOCKETSV = ScopedValue.newInstance(); void serve(ServerSocket serverSocket) throws IOException 我们的动态作用域示例展示了关键模式的实际应用: 使用static final作为作用域值的holder 在类作用域中声明 ScopedValue 实例 在方法中创建动态作用域(如 runWhere() <SecurityLevel> securitySV = ScopedValue.newInstance(); private static final ScopedValue<Integer> requestSV = ScopedValue.newInstance(); private final AtomicInteger req = new AtomicInteger(); public
来个: private static final ScopedValue<FrameworkContext> CONTEXT = ScopedValue.newInstance 例如,在结构化并发中,ScopedValue 的生命周期与任务作用域对齐,确保子任务结束时自动释放资源。 2. 不可变性设计 ScopedValue 是不可变的(Immutable),一旦绑定值后无法修改,这消除了多线程环境下因共享可变状态引发的线程安全问题。 内存效率与性能优化 根据 JDK 官方测试数据,ScopedValue 在相同并发规模下相比 ThreadLocal 可节省高达 40% 的内存资源。 专为虚拟线程优化 ScopedValue 针对 Java 虚拟线程(Virtual Thread)设计,支持高效的线程本地数据管理。
20+36-2344, mixed mode, sharing) 从version信息可以看出是build 20+36 特性列表 JEP 429: Scoped Values (Incubator) ScopedValue ScopedValue则提供了一种不可变、不拷贝的方案,即不提供set方法,子线程不需要拷贝就可以访问父线程的变量。 具体使用如下: class Server { public final static ScopedValue<User> LOGGED_IN_USER = ScopedValue.newInstance User loggedInUser = authenticateUser(request); ScopedValue.where(LOGGED_IN_USER, loggedInUser) .run(() -> restAdapter.processRequest(request)); // ... } } 通过ScopedValue.where可以绑定ScopedValue的值
public class ScopedValueExample { final static ScopedValue<String> LoginUser = ScopedValue.newInstance (); public static void main(String[] args) throws InterruptedException { ScopedValue.where login() { System.out.println("user:" + LoginUser.get()); } } } 上面的示例模拟了用户登录过程,使用ScopedValue.newInstance ()声明了一个ScopedValue,使用ScopedValue.where为ScopedValue设置了一个值,并使用run方法执行接下来要做的事情,以便在run()内部随时获取ScopedValue
作用域值(Scoped Values) 替代 ThreadLocal,提供更安全、轻量的线程内数据共享机制: final ScopedValue<String> USER = ScopedValue.newInstance (); ScopedValue.where(USER, "Alice").run(() -> System.out.println(USER.get())); 避免内存泄漏问题,生命周期严格绑定作用域
被同组实习生吓一跳,他竟然知道InheritableThreadLocal和TransmittableThreadLocal 2024-11-02 于是JDK24推出了ScopedValue来解决解决虚拟线程场景下的上下文共享与内存泄漏问题 : ScopedValue<String> scopeVal = ScopedValue.newInstance(); ScopedValue.where(scopeVal, "B").run(() - 后续我会单独出一篇文章讲解ScopedValue。
新版写法 import java.lang.ScopedValue; public class ScopedValueExample { private static final ScopedValue <String> USER_ID = ScopedValue.newInstance(); public static void main(String[] args) throws Exception { ScopedValue.where(USER_ID, "user123").run(() -> { System.out.println("Current
import jdk.incubator.concurrent.ScopedValue;public class AuditCtx { static final ScopedValue<String > CORRELATION_ID = ScopedValue.newInstance(); static void handleRequest(String corrId, Runnable handler ) { ScopedValue.where(CORRELATION_ID, corrId).run(handler); } static void serviceCall()
-Djdk.tracePinnedThreads=full -jar app.jar内存优化技巧// 避免在虚拟线程中使用大对象ThreadLocalprivate static final ScopedValue <Connection> DB_CONN = ScopedValue.newInstance();public void handleRequest() { ScopedValue.where
作用域值(Scoped Values)(JEP 506)替代 ThreadLocal 的新方案,跨线程共享上下文更安全:static final ScopedValue<String> USER_ID = ScopedValue.newInstance();void handle(String userId) { ScopedValue.where(USER_ID, userId).run(()
ScopedValue<User> CONTEXT = ScopedValue.newInstance(); CONTEXT.with(new User("Alice"), () -> { /* 当前线程内可用
Values (Preview) Scoped Values在JDK20的JEP 429: Scoped Values (Incubator)作为Incubator 此次在JDK21作为preview版本 ScopedValue ScopedValue则提供了一种不可变、不拷贝的方案,即不提供set方法,子线程不需要拷贝就可以访问父线程的变量。 具体使用如下: class Server { public final static ScopedValue<User> LOGGED_IN_USER = ScopedValue.newInstance User loggedInUser = authenticateUser(request); ScopedValue.where(LOGGED_IN_USER, loggedInUser) .run(() -> restAdapter.processRequest(request)); // ... } } 通过ScopedValue.where可以绑定ScopedValue
Values (Preview) Scoped Values在JDK20的JEP 429: Scoped Values (Incubator)作为Incubator 此次在JDK21作为preview版本 ScopedValue ScopedValue则提供了一种不可变、不拷贝的方案,即不提供set方法,子线程不需要拷贝就可以访问父线程的变量。 具体使用如下: class Server { public final static ScopedValue<User> LOGGED_IN_USER = ScopedValue.newInstance User loggedInUser = authenticateUser(request); ScopedValue.where(LOGGED_IN_USER, loggedInUser) .run(() -> restAdapter.processRequest(request)); // ... } } 通过ScopedValue.where可以绑定ScopedValue的值
446: Scoped Values (Preview)作为preview版本JDK22作为第二次preview,具体使用如下:class Server { public final static ScopedValue <User> LOGGED_IN_USER = ScopedValue.newInstance(); private void serve(Request request) { // ... User loggedInUser = authenticateUser(request); ScopedValue.where(LOGGED_IN_USER, loggedInUser) .run(() -> restAdapter.processRequest(request)); // ... }}通过ScopedValue.where可以绑定ScopedValue的值,然后在
: Scoped Values (Preview)作为preview版本 JDK22作为第二次preview,具体使用如下: class Server { public final static ScopedValue <User> LOGGED_IN_USER = ScopedValue.newInstance(); private void serve(Request request) { // . User loggedInUser = authenticateUser(request); ScopedValue.where(LOGGED_IN_USER, loggedInUser) .run(() -> restAdapter.processRequest(request)); // ... } } 通过ScopedValue.where可以绑定ScopedValue
优点 缺点 ThreadLocal 简单高效 内存泄漏风险 ScopedValue