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

Java 21:虚拟线程介绍

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

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

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

平台线程

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

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

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

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

每个请求一个线程

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

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

使用线程池

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

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

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

轻量级线程

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

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

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

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

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

虚拟线程

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

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

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

物美价廉

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

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

设定界限

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

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

代码展示

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

创建平台线程

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

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

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

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

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

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

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

创建虚拟线程

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

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

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

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

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

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

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

总结

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

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

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

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

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

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

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

标签:
  • 热门焦点
  • MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • 7月安卓手机性价比榜:努比亚+红魔两款新机入榜

    7月登场的新机有努比亚Z50S Pro和红魔8S Pro,除了三星之外目前唯二的两款搭载超频版骁龙8Gen2处理器的产品,而且努比亚和红魔也一贯有着不错的性价比,所以在本次的性价比榜单
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • 不容错过的MSBuild技巧,必备用法详解和实践指南

    一、MSBuild简介MSBuild是一种基于XML的构建引擎,用于在.NET Framework和.NET Core应用程序中自动化构建过程。它是Visual Studio的构建引擎,可在命令行或其他构建工具中使用
  • 微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • OPPO、vivo、小米等国内厂商Q2在印度智能手机市场份额依旧高达55%

    7月20日消息,据外媒报道,研究机构的报告显示,在全球智能手机出货量同比仍在下滑的大背景下,印度这一有潜力的市场也未能幸免,出货量同比也有下滑,多家厂
  • Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
Top