13、Java 21 新特性 - 作用域值(预览)

引入作用域值,这些值可以在不使用方法参数的情况下安全有效地共享给方法。它们优先于线程化局部变量,尤其是在使用大量虚拟线程时。这是一个预览API。

实际上,作用域值是一个隐式方法参数。这“就好像”一系列调用中的每个方法都有一个额外的、不可见的参数。没有任何方法声明此参数,只有能够访问作用域值对象的方法才能访问其值(数据)。通过作用域值,可以通过一系列中间方法将数据从调用者安全地传递给遥远的被调用者,这些中间方法不声明数据的参数,也无法访问数据。

我们一定使用过ThreadLocal,它是线程本地变量,只要线程不销毁,就可以随时获取ThreadLocal中的变量值。作用域值也可以在线程内的任何时候获取变量,但它有一个作用域的概念,当超出作用域时将被销毁。

public class ScopedValueExample {
    final static ScopedValue<String> LoginUser = ScopedValue.newInstance();
 
 
    public static void main(String[] args) throws InterruptedException {
        ScopedValue.where(LoginUser, "Tom")
                   .run(() -> {
                       new Service().login();
                   });
 
 
        Thread.sleep(2000);
    }
 
 
    static class Service {
        void login() {
            System.out.println("user:" + LoginUser.get());
        }
    }
}

上面的示例模拟了用户登录过程,使用ScopedValue.newInstance()声明了一个ScopedValue,使用ScopedValue.where为ScopedValue设置了一个值,并使用run方法执行接下来要做的事情,以便在run()内部随时获取ScopedValue。在run方法中模拟了service的登录方法,不需要传递参数LoginUser,直接通过LoginUser.get方法可以直接获取当前登录用户的值。