当前位置:首页 > 科技  > 软件

Java 21:虚拟线程介绍

来源: 责编: 时间:2023-10-10 18:32:02 383观看
导读Java 21 版本更新中最重要的功能之一就是虚拟线程 (JEP 444)。这些轻量级线程减少了编写、维护和观察高吞吐量并发应用程序所需的工作量。正如我的许多其他文章一样,在推出新功能之前,让我们先看看 Java 21 版本更新前

Java 21 版本更新中最重要的功能之一就是虚拟线程 (JEP 444)。这些轻量级线程减少了编写、维护和观察高吞吐量并发应用程序所需的工作量。ZYg28资讯网——每日最新资讯28at.com

正如我的许多其他文章一样,在推出新功能之前,让我们先看看 Java 21 版本更新前的现状,以便更好地了解 Java 21 版本试图解决的问题以及好处是什么。ZYg28资讯网——每日最新资讯28at.com

平台线程

在引入虚拟线程之前,java.lang.Thread 包已经支持所谓的平台线程。ZYg28资讯网——每日最新资讯28at.com

这些线程通常以 1:1 的方式映射到操作系统调度的内核线程。操作系统线程相当“重”。这使得它们可以执行所有类型的任务。ZYg28资讯网——每日最新资讯28at.com

根据操作系统和 JVM 启动参数配置的不同,一个平台线程默认消耗 1 MB 的空间。因此如果我们想在重负载高并发应用程序中使用一百万个线程,我们最好有超过 1 TB 的空闲内存!ZYg28资讯网——每日最新资讯28at.com

如上所述,平台线程有一个明显的内存瓶颈限制了我们实际上可以拥有的线程数量。ZYg28资讯网——每日最新资讯28at.com

每个请求一个线程

每个请求使用单个线程有很多优点,例如更容易的状态管理和清理。但它也造成了可扩展性限制。应用程序的“并发单元”(在本例中为请求)需要单个“并发平台单元”(在本例中也就是平台线程),但是在重负载高并发应用程序中,平台线程容易因为内存不足、CPU 资源耗尽而创建失败。ZYg28资讯网——每日最新资讯28at.com

尽管“每个请求一个线程”有很多优点,平台线程可以更均匀地利用硬件,但我们还是需要一种完全不同的方法。ZYg28资讯网——每日最新资讯28at.com

使用线程池

与在单个线程上处理以个请求不同,当任务完成时,线程会被线程池回收,因此另一个请求可能会重用相同的线程。这允许我们的程序使用更少的线程处理更多的请求,但会带来异步编程的负担。ZYg28资讯网——每日最新资讯28at.com

异步编程具有自己的范例,具有一定的学习曲线,并且可能使我们的程序更难以理解和遵循。请求的每个部分可能在不同的线程上执行,在没有合理上下文的情况下创建堆栈跟踪,并使调试变得非常棘手甚至几乎不可能。ZYg28资讯网——每日最新资讯28at.com

重新审视“每个请求一个线程”模型,很明显,我们需要一种更轻量级的线程方法来解决这个瓶颈,并最好按照我们熟悉的方式。ZYg28资讯网——每日最新资讯28at.com

轻量级线程

由于平台线程的数量在不新增硬件资源的情况下无法改变,因此也就需要另一层抽象,以切断首先产生瓶颈的可怕的 1:1 映射。ZYg28资讯网——每日最新资讯28at.com

轻量级线程不依赖于特定的平台线程,也不会为其分配大量内存。它们由运行时的 JVM 调度和管理而不是底层操作系统。这就是为什么可以创建大量轻量级线程的原因。ZYg28资讯网——每日最新资讯28at.com

轻量级线程的概念并不新鲜,许多语言都有某种形式的轻量级线程:ZYg28资讯网——每日最新资讯28at.com

  • Go 语言中的 Goroutines(协程)
  • Erlang 语言中的 Processes(轻量级进程)
  • Haskell Threads

Java 也在 21 版本中引入了自己的轻量级线程实现:虚拟线程。ZYg28资讯网——每日最新资讯28at.com

虚拟线程

虚拟线程是一个新的轻量级 java.lang.Thread 变体,是 Project Loom 项目的一部分,不由操作系统管理或调度。相反由 JVM 负责调度。当然在实际工作反映到操作系统还是以平台线程运行,但 JVM 正是利用所谓的载体线程(即平台线程)来“承载”虚拟线程,以便在需要时执行。ZYg28资讯网——每日最新资讯28at.com

JVM / OS 线程调度示意图JVM / OS 线程调度示意图ZYg28资讯网——每日最新资讯28at.com

所需的平台线程以 FIFO 工作方式在 ForkJoinPool 中进行管理,默认情况下,它使用所有可用的处理器,但可以通过调整系统属性 jdk.virtualThreadScheduler.parallelism 来根据我们的要求进行修改。我们熟悉的 ForkJoinPool 与并行流等其他功能使用的公共池之间的主要区别在于,公共池以 LIFO 模式运行。ZYg28资讯网——每日最新资讯28at.com

物美价廉

虚拟线程是廉价且轻量级的,我们可以使用“每个请求一个线程”模型,而不必担心实际需要多少个线程。如果我们的代码在虚拟线程中调用阻塞 I/O 操作,则运行时会挂起这个被阻塞的虚拟线程,直到挂起结束后就可以恢复。这样一来,程序对硬件的利用就可以达到近乎最佳并提供高水平的并发性,从而实现高吞吐量。ZYg28资讯网——每日最新资讯28at.com

因为虚拟线程非常便宜,所以虚拟线程不会被重用或需要被池化。每个任务都由其自己的虚拟线程来执行。ZYg28资讯网——每日最新资讯28at.com

设定界限

JVM 调度程序通过载体线程来管理虚拟线程,因此需要一定的边界和分隔来确保可能的“无数”虚拟线程按预期运行。这是通过在载体线程和它可能承载的任何虚拟线程之间保持无线程关联来实现的:ZYg28资讯网——每日最新资讯28at.com

  • 虚拟线程无法访问载体线程,Thread.currentThread() 返回虚拟线程本身。
  • 堆栈跟踪是独立的,虚拟线程中抛出的任何异常仅包含其自己的堆栈帧。
  • 虚拟线程的线程局部变量对其载体线程不可用,反之亦然。
  • 从代码的角度来看,载体线程及其虚拟线程对平台线程的共享是不可见的。

代码展示

在我看来,虚拟线程最好的事情之一就是我们不需要学习新的编程范例或复杂的新 API,就能够完成异步编程。在使用上,我们可以像对待平台线程一样对待虚拟线程。ZYg28资讯网——每日最新资讯28at.com

创建平台线程

创建平台线程很简单,就像使用 Runnable 创建一样:ZYg28资讯网——每日最新资讯28at.com

Runnable fn = () -> {  // your code here};Thread thread = new Thread(fn).start();

随着 Project Loom 项目简化了新的并发方法,还提供了一种创建平台线程的新方法:ZYg28资讯网——每日最新资讯28at.com

Thread thread = Thread.ofPlatform().                      .start(runnable);

实际上,现在有一个完整的 Fluent API,因为 ofPlatform() 返回一个 Thread.Builder.OfPlatform 实例:ZYg28资讯网——每日最新资讯28at.com

Thread thread = Thread.ofPlatform().                      .daemon()                      .name("my-custom-thread")                      .unstarted(runnable);

但你来这里显然不是为了学习创建“旧”线程的新方法,你想要新的东西!ZYg28资讯网——每日最新资讯28at.com

创建虚拟线程

对于虚拟线程,同样有一个 Fluent API:ZYg28资讯网——每日最新资讯28at.com

Runnable fn = () -> {  // your code here};Thread thread = Thread.ofVirtual(fn)                      .start();

除了构建器方法之外,我们还可以直接使用以下命令创建虚拟线程:ZYg28资讯网——每日最新资讯28at.com

Thread thread = Thread.startVirtualThread(() -> {  // your code here});

由于所有虚拟线程始终都是守护线程,因此如果我们想在主线程上等待虚拟线程执行完毕,可以调用 join() 方法。ZYg28资讯网——每日最新资讯28at.com

创建虚拟线程的另一种方法是使用 Executor 类:ZYg28资讯网——每日最新资讯28at.com

var executorService = Executors.newVirtualThreadPerTaskExecutor();executorService.submit(() -> {  // your code here});

总结

尽管作用域值 (JEP 446) 和结构化并发 (JEP 453) 仍然是 Java 21 中的预览功能,但虚拟线程已经成为可投入生产的成熟功能。ZYg28资讯网——每日最新资讯28at.com

虚拟线程是一种通用且强大的 Java 并发新方式,将对我们的未来程序产生重大影响。虚拟线程使用熟悉且可靠的“每个请求一个线程”方法,同时以最佳方式利用所有可用硬件,无需学习新范例或复杂的 API。ZYg28资讯网——每日最新资讯28at.com

本文翻译自国外论坛 medium,原文地址:https://medium.com/@benweidig/looking-at-java-21-virtual-threads-0ddda4ac1be1ZYg28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-12741-0.htmlJava 21:虚拟线程介绍

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 深入解析整洁架构 Clean Architecture:构建灵活、测试维护的应用

下一篇: 使用 Helm 管理应用的一些 Tips

标签:
  • 热门焦点
  • 一加Ace2 Pro真机揭晓 钛空灰配色质感拉满

    终于,在经过了几波预热之后,一加Ace2 Pro的外观真机图在网上出现了。还是博主数码闲聊站曝光的,这次的外观设计还是延续了一加11的方案,只是细节上有了调整,例如新加入了钛空灰
  • 对标苹果的灵动岛 华为带来实况窗功能

    继苹果的灵动岛之后,华为也在今天正式推出了“实况窗”功能。据今天鸿蒙OS 4.0的现场演示显示,华为的实况窗可以更高效的展现出实时通知,比如锁屏上就能看到外卖、打车、银行
  • 小米平板5 Pro 12.4简评:多专多能 兼顾影音娱乐的大屏利器

    疫情带来了网课,网课盘活了安卓平板,安卓平板市场虽然中途停滞了几年,但好的一点就是停滞的这几年行业又有了新的发展方向,例如超窄边框、高刷新率、多摄镜头组合等,这就让安卓
  • 6月安卓手机好评榜:魅族20 Pro蝉联冠军

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年6月1日至6月30日,仅限国内市场。第一名:魅族20 Pro好评率:95%5月份的时候魅族20 Pro就是
  • 如何使用JavaScript创建一只图像放大镜?

    译者 | 布加迪审校 | 重楼如果您曾经浏览过购物网站,可能遇到过图像放大功能。它可以让您放大图像的特定区域,以便浏览。结合这个小小的重要功能可以大大改善您网站的用户体验
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • AMD的AI芯片转单给三星可能性不大 与台积电已合作至2nm制程

    据 DIGITIMES 消息,英伟达 AI GPU 出货逐季飙升,接下来 AMD MI 300 系列将在第 4 季底量产。而半导体业内人士表示,近日传出 AMD 的 AI 芯片将转单给
  • Windows 11发布,微软一改往常对老机型开放的态度

    距离 Windows 11 发布已经过去一周,在过去一周里,很多数码爱好者围绕其对 Android 应用的支持、对老机型的升级问题展开了激烈讨论。与以往不同的是,在这次大
  • “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主“七王”在群里介绍一些刷单赚
Top