写点什么

JEP 481:作用域值 API 的第 3 个预览版随 JDK 23 发布,带来关键增强

  • 2024-08-12
    北京
  • 本文字数:1628 字

    阅读完需:约 5 分钟

JEP 481:作用域值API的第3个预览版随JDK 23发布,带来关键增强

JEP 481(作用域值第 3 个预览版)——之前称为范围局部变量(孵化)——提供了第三次预览。该版本只有一个变化,旨在从之前的一轮孵化和两轮预览之外获得额外的经验和反馈:随 JDK 22 交付的 JEP 464(作用域值第 2 个预览版)、随 JDK 21 交付的 JEP 446(作用域值预览版)以及随 JDK 20 交付的 JEP 429(作用域值孵化)。该特性支持在线程内部和线程之间共享不可变数据。


在 JDK 23 中重新预览的作用域值 API 修改了ScopedValue.callWhere方法。现在,这个方法的操作参数是一个函数式接口。它允许 Java 编译器推断是否可能抛出检查异常。因此,ScopedValue.getWhere这个方法就不再需要了,而且已经删除。在频繁共享数据的场景中,这会使代码更简洁,而且性能更好。


作用域值使方法能够与其调用者和子线程共享不可变数据。与线程局部变量相比,这可以简化数据流的管理和推断。而且,它们的空间和时间成本更低,特别是在与虚拟线程(JEP 444)和结构化并发(JEP 480)结合使用时。


不过,Java 1.2 中引入的线程局部变量一直是一个简化同一线程内方法间数据共享的传统方法。尽管已经使用了很长时间,但它还是有一些缺点。一个主要的问题是它们毫无约束的可变性,任何代码都可以随时更改线程局部变量的值,这可能导致潜在的不一致。另一个缺点是它们的寿命不受限制;如果开发人员忘记调用remove方法,值的保存时长可能会超过所需的时长,而这通常会导致内存泄漏。此外,跨线程继承线程局部变量会显著增加开销,因为每个子线程都必须为先前在父线程中写入的每个线程局部变量分配存储空间,这会对性能产生负面影响。


作用域值解决了这个问题,它确保数据是不可变的,并且只能在定义好的作用域中访问。这增强了安全性和性能。


为了说明作用域值的好处,考虑下这样一个 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); }}
复制代码


使用作用域值,其实现会变得更加简洁、高效:


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); }}
复制代码


使用线程局部变量,当框架调用用户代码以及当用户代码回调框架方法时,不需要将FrameworkContext作为方法的参数进行传递。线程局部变量是作为一个隐藏的方法参数:线程调用Framework.serve中的CONTEXT.set。然后,Framework.readKey中的CONTEXT.get自动就可以看到CONTEXT的本地副本。实际上,ThreadLocal字段充当了一个键,用于查找当前线程的FrameworkContext值。另一方面,使用作用域值简化了这个过程。它消除了可变状态,并且确保上下文只能在runWhere方法定义好的范围内访问,从而提供了一种更健壮且性能更好的方法。总之,作用域值 API 显著增强了 Java 中跨方法和线程共享数据的方式,促进了更好的编码实践,并提高了应用程序的性能。它非常符合现代并发模型,特别是当虚拟线程出现之后,它为开发人员处理高并发应用程序提供了一个重要的选项。


原文链接:

https://www.infoq.com/news/2024/07/jep-481-enhanced-scoped-values/

2024-08-12 08:005827

评论

发布
暂无评论
发现更多内容

Hoo虎符研究院 | 币海寻珠——即将初始发行Token区块链项目

区块链前沿News

Hoo 虎符交易所 初始发行

数字化进程中,如何保证数据安全?

CECBC

从“看得清”到“看得懂”:视域提升带来的管理“魔法”

脑极体

跟着动画学习GO数据结构之Go链表

宇宙之一粟

数据结构 链表 Go 语言 1月月更

从事【音视频】的开发者,看过来,如果记不住FFmepg命令,可以收藏,不记得的时候,掏出来翻翻

奔着腾讯去

c 音视频 ffmpeg

软件定义存储的头部厂商也来了,XSKY 星辰天合加入龙蜥社区

OpenAnolis小助手

龙蜥社区

云原生训练营--毕业总结

施正威

智感超清,有多智?有多清?

百度大脑

人工智能

架构实战营模块四课后作业

Jude

架构实战营

跟一段工作说告别了

wood

300天创作

Flutter 压缩图像的最佳方式

坚果

flutter 1月月更

session利用的小思路

网络安全学海

网络安全 安全 信息安全 渗透测试 安全漏洞

架构实战营:模块四作业

Geek_93ffb0

「架构实战营」

LabVIEW色彩匹配实现颜色识别、颜色检验(基础篇—13)

不脱发的程序猿

机器视觉 LabVIEW 颜色识别 颜色检验 色彩匹配

VuePress 博客优化之 last updated 最后更新时间如何设置

冴羽

JavaScript Vue 前端 博客 vuepress

当云服务变成云云云云服务,谁能带领企业穿越云层?

脑极体

四位一体水溶交融,Docker一拖三Tornado6.2 + Nginx + Supervisord非阻塞负载均衡容器式部署实践

刘悦的技术博客

nginx tornado Supervisor ,docker docker image

【架构师训练营】模块四作业

樰巳-堕~Horry

架构实战营 「架构实战营」

你了解集合?那你倒是给我说说啊!【3】

XiaoLin_Java

集合 java基础 1月月更

微信小程序与webview关于iphone X的兼容设置

CRMEB

为什么都是ViewGroup的LayoutParams,也会报cannot be cast to android.view.ViewGroup$MarginLayoutParams?

程思扬

andiod

Hoo虎符研究院 | 币海寻珠——2021年4季度区块链投融事件TOP20

区块链前沿News

Hoo虎符 虎符交易所 虎符研究院 区块链投融 灰度基金

点外卖也可用数字人民币,国内零售支付产业体系全面升级

CECBC

数据并行:提升训练吞吐的高效方法 |深度学习分布式训练专题

百度大脑

网络安全——防止被抓包

喀拉峻

网络安全 信息安全 抓包

Tableau Day4:时间分析

贾献华

Tableau 1月月更

粤、蒙、沪同步试点全电发票,数字化转型思路你拿捏了吗?

金小K

性能工具之 Loadrunner 常见脚本开发

zuozewei

性能测试 LoadRunner 1月月更

07 Prometheus之服务发现

穿过生命散发芬芳

Prometheus 1月月更

一个cpp协程库的前世今生(十三)互斥量

SkyFire

c++ cocpp

开源的安全可信治理与区块链

CECBC

JEP 481:作用域值API的第3个预览版随JDK 23发布,带来关键增强_编程语言_A N M Bazlur Rahman_InfoQ精选文章