JEP 481:在JDK 23中引入Scoped Values API的第三次预览,带来关键增强

JEP 481:Scoped Values(第三次预览)

JEP 481,即Scoped Values(第三次预览),已为JDK 23完成。该JEP在经历了孵化阶段和两次预览阶段后,提供了第三次预览版本,旨在通过引入一个变更来获取更多的经验和反馈。此前的相关JEP包括:

  • JEP 464(JDK 22):Scoped Values(第二次预览)
  • JEP 446(JDK 21):Scoped Values(预览)
  • JEP 429(JDK 20):Scoped Values(孵化)

Scoped Values 允许在线程内部和跨线程之间共享不可变数据,相较于传统的线程局部变量(Thread-Local Variables),它更适用于大量虚拟线程(Virtual Threads)的场景。

主要变更

在JDK 23中,Scoped Values API 的重新预览引入了一个重要变更:ScopedValue.callWhere 方法的操作参数现在是一个函数式接口。这一变更使得Java编译器能够推断是否可能抛出受检异常。因此,ScopedValue.getWhere 方法不再需要,已被移除。这不仅简化了代码,还提升了在频繁数据共享场景下的性能。

Scoped Values 的优势

Scoped Values 使方法能够与被调用者子线程共享不可变数据,相较于线程局部变量,它更易于管理和推理数据流。其空间和时间成本更低,尤其是在与虚拟线程(JEP 444)结构化并发(JEP 480)结合使用时。

线程局部变量的局限性

线程局部变量自 Java 1.2 引入,是传统的数据共享方式,但也存在一些显著缺点:

  1. 无约束的易变性:任何代码都可以随时修改线程局部变量的值,可能导致不一致性。
  2. 无限的生命周期:值可能比实际需要的时间更长,如果开发者忘记调用remove方法,可能导致内存泄漏。
  3. 线程间继承的高开销:每个子线程必须为父线程中写入的每个线程局部变量分配存储空间,显著影响性能。

Scoped Values 通过确保数据不可变且仅在定义的作用域内可访问,解决了上述问题,从而提升了安全性性能

示例对比

Web框架为例,假设需要在不同方法之间共享上下文而不显式传递参数。

使用线程局部变量的实现

class Framework {
  private final static ThreadLocal<FrameworkContext> CONTEXT = new ThreadLocal<>();

  void serve(Request request, Response response) {
    var context = createContext(request);
    CONTEXT.set(context);
    Application.handle(request, response);
  }

  public PersistedObject readKey(String key) {
    var context = CONTEXT.get();
    var db = getDBConnection(context);
    return db.readKey(key);
  }
}

使用Scoped Values的实现

class Framework {
  private final static ScopedValue<FrameworkContext> CONTEXT = ScopedValue.newInstance();

  void serve(Request request, Response response) {
    var context = createContext(request);
    ScopedValue.runWhere(CONTEXT, context, () -> Application.handle(request, response));
  }

  public PersistedObject readKey(String key) {
    var context = CONTEXT.get();
    var db = getDBConnection(context);
    return db.readKey(key);
  }
}

总结

Scoped Values API 显著改善了 Java 中跨方法和线程共享数据的方式,推动了更好的编码实践并提升了应用性能。它特别适用于现代并发模型,尤其是在虚拟线程的背景下,成为开发高并发应用的重要工具。

阅读 86
0 条评论