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

Java 21 的虚拟线程:高性能并发应用的福音

来源: 责编: 时间:2023-12-08 09:14:12 311观看
导读Java 21 最重要的特性之一就是虚拟线程 (JEP 444)。这些轻量级的线程降低了编写、维护和观察高吞吐量并行应用所需的努力。在讨论新特性之前,让我们先看一下当前的状态,以便更好地理解它试图解决什么问题以及带来了哪些

Java 21 最重要的特性之一就是虚拟线程 (JEP 444)。这些轻量级的线程降低了编写、维护和观察高吞吐量并行应用所需的努力。AxM28资讯网——每日最新资讯28at.com

在讨论新特性之前,让我们先看一下当前的状态,以便更好地理解它试图解决什么问题以及带来了哪些好处。AxM28资讯网——每日最新资讯28at.com

平台线程

在引入虚拟线程之前,我们习惯使用的线程是 java.lang.Thread,它背后是所谓的平台线程 (platform threads)。AxM28资讯网——每日最新资讯28at.com

这些线程通常与操作系统调度的内核线程一一映射。操作系统线程相当“重”,这使得它们适合执行所有类型的任务。AxM28资讯网——每日最新资讯28at.com

根据操作系统和配置,它们默认情况下会消耗大约2到10 MB的内存。因此,如果你想在高负载并发应用程序中使用一百万个线程,最好要有超过2 TB的可用内存!AxM28资讯网——每日最新资讯28at.com

这存在一个明显的瓶颈,限制了我们实际可以在没有缺点的情况下拥有的线程数量。AxM28资讯网——每日最新资讯28at.com

每个请求一个线程

这很成问题,因为它直接与典型的服务器应用程序“每个请求一个线程”的方法相冲突。使用每个请求一个线程有很多优点,例如更简单的状态管理和清理。但它也创造了可扩展性限制。应用程序的“并发单位”,在这种情况下是一个请求,需要一个“平台并发单位”。因此,线程很容易被原始CPU能力或网络耗尽。AxM28资讯网——每日最新资讯28at.com

即使“每个请求一个线程”有许多优点,共享重量级的线程可以更均匀地利用硬件,但也需要一种完全不同的方法。AxM28资讯网——每日最新资讯28at.com

异步救援

而不是在单个线程上运行整个请求,它的每个部分都从池中使用一个线程,当它们的任务完成时,另一个任务可能会重用同一个线程。这允许代码需要更少的线程,但引入了异步编程的负担。AxM28资讯网——每日最新资讯28at.com

异步编程伴随着它自己的范例,具有一定的学习曲线,并且可能会使程序更难理解和跟踪。请求的每个部分可能都在不同的线程上执行,从而创建没有合理上下文的堆栈跟踪,并使调试某些内容变得非常棘手甚至几乎不可能。AxM28资讯网——每日最新资讯28at.com

Java有一个用于异步编程的优秀API,CompletableFuture。但这是一个复杂的API,并且不太适合许多Java开发人员习惯的思维方式。AxM28资讯网——每日最新资讯28at.com

重新审视“每个请求一个线程”模型,很明显,一种更轻量级的线程方法可以解决瓶颈并提供一种熟悉的做事方式。AxM28资讯网——每日最新资讯28at.com

轻量级线程

由于平台线程的数量是无法在没有更多硬件的情况下改变的,因此需要另一个抽象层,切断可怕的 1:1 映射,它是首先造成瓶颈的原因。AxM28资讯网——每日最新资讯28at.com

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

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

  • Go 语言中的 Goroutine
  • Erlang 进程
  • Haskell 线程
  • 等等

Java最终于第21版中引入了自己的轻量级线程实现:虚拟线程 (Virtual Threads)。AxM28资讯网——每日最新资讯28at.com

虚拟线程

虚拟线程是一种新的轻量级java.lang.Thread变体,是Project Loom的一部分,它不是由操作系统管理或调度的。相反,JVM负责调度。AxM28资讯网——每日最新资讯28at.com

当然,任何实际的工作都必须在平台线程中运行,但是JVM使用所谓的“载体线程”(carrier threads) 来“携带”任何虚拟线程,以便在它们需要执行时执行这些线程。AxM28资讯网——每日最新资讯28at.com

图片图片AxM28资讯网——每日最新资讯28at.com

JVM/操作系统线程调度器AxM28资讯网——每日最新资讯28at.com

所需的平台线程在一个 FIFO 工作窃取 ForkJoinPool 中进行管理,该池默认情况下使用所有可用的处理器,但可以通过调整系统属性jdk.virtualThreadScheduler.parallelism来根据需求进行修改。AxM28资讯网——每日最新资讯28at.com

ForkJoinPool与其他功能(例如并行流)使用的通用池之间的主要区别在于,通用池以LIFO模式运行。AxM28资讯网——每日最新资讯28at.com

廉价且丰富的线程

拥有廉价且轻量级的线程,可以使用“每个请求一个线程”模型,而不必担心实际需要多少个线程。如果你的代码在虚拟线程中调用阻塞 I/O 操作,则运行时会挂起虚拟线程,直到它可以稍后恢复。AxM28资讯网——每日最新资讯28at.com

这样,硬件就可以被优化到几乎最佳的水平,从而实现高水平的并发性,因此也实现高吞吐量。AxM28资讯网——每日最新资讯28at.com

因为它们非常廉价,所以虚拟线程不会被重用或需要池化。每个任务都由其自己的虚拟线程表示。AxM28资讯网——每日最新资讯28at.com

设置边界

调度器负责管理载体线程,因此需要一定的边界和分离,以确保可能的“无数”虚拟线程按照预期运行。这是通过在载体线程及其可能携带的任何虚拟线程之间不保持线程关联来实现的:AxM28资讯网——每日最新资讯28at.com

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

让我们看看代码

使用Virtual Threads最大的好处是,你不需要学习新的范例或复杂的API,就像使用异步编程一样。相反,你可以像对待非虚拟线程一样处理它们。AxM28资讯网——每日最新资讯28at.com

创建平台线程

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

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

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

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

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

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

但你肯定不是来学习创建“旧”线程的新方法的,我们想要一点新的东西。继续看。AxM28资讯网——每日最新资讯28at.com

创建虚拟线程

对于虚拟线程,也有类似的fluent API:AxM28资讯网——每日最新资讯28at.com

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

除了构建器方法之外,你还可以直接使用以下方式执行Runnable:AxM28资讯网——每日最新资讯28at.com

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

由于所有虚拟线程始终是守护线程,因此如果你想在主线程上等待,请不要忘记调用join()。AxM28资讯网——每日最新资讯28at.com

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

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

小结

尽管Scoped Values (JEP 446) 和Structured Concurrency (JEP 453) 仍然是Java 21中的预览功能,但Virtual Threads已经成为一个成熟的、适用于生产环境的功能。AxM28资讯网——每日最新资讯28at.com

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

本文链接:http://www.28at.com/showinfo-26-39505-0.htmlJava 21 的虚拟线程:高性能并发应用的福音

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

上一篇: 你 UTF-8 乱码,关我 Unicode 什么事

下一篇: 一款小而美的开源滑动验证码组件

标签:
  • 热门焦点
  • JavaScript学习 -AES加密算法

    引言在当今数字化时代,前端应用程序扮演着重要角色,用户的敏感数据经常在前端进行加密和解密操作。然而,这样的操作在网络传输和存储中可能会受到恶意攻击的威胁。为了确保数据
  • 三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 小红书1周涨粉49W+,我总结了小白可以用的N条涨粉笔记

    作者:黄河懂运营一条性教育视频,被54万人“珍藏”是什么体验?最近,情感博主@公主是用鲜花做的,火了!仅仅凭借一条视频,光小红书就有超过128万人,为她疯狂点赞!更疯狂的是,这
  • 中国家电海外掘金正当时|出海专题

    作者|吴南南编辑|胡展嘉运营|陈佳慧出品|零态LT(ID:LingTai_LT)2023年,出海市场战况空前,中国创业者在海外纷纷摩拳擦掌,以期能够把中国的商业模式、创业理念、战略打法输出海外,他们依
  • 猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对“势”的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 华为Mate 60保护壳曝光:硕大后置相机模组 凸起程度有惊喜

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • 苹果140W USB-C充电器:采用氮化镓技术

    据10 月 30 日 9to5 Mac 消息报道,当苹果推出新的 MacBook Pro 2021 时,该公司还推出了新的 140W USB-C 充电器,附赠在 MacBook Pro 16 英寸机型的盒子里,也支
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
  • 北京:科技教育体验基地开始登记

      北京“科技馆之城”科技教育体验基地登记和认证工作日前启动。首批北京科技教育体验基地拟于2023年全国科普日期间挂牌,后续还将开展常态化登记。  北京科技教育体验基
Top