当前位置: 首页 > news >正文

Java 21:虚拟线程介绍

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

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

一、平台线程

在引入虚拟线程之前,java.lang.Thread 包已经支持所谓的平台线程。

这些线程通常以 1:1 的方式映射到操作系统调度的内核线程。操作系统线程相当“重”。这使得它们可以执行所有类型的任务。

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

如上所述,平台线程有一个明显的内存瓶颈限制了我们实际上可以拥有的线程数量。

1.每个请求一个线程

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

尽管“每个请求一个线程”有很多优点,平台线程可以更均匀地利用硬件,但我们还是需要一种完全不同的方法。

2.使用线程池

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

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

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

3.轻量级线程

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

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

轻量级线程的概念并不新鲜,许多语言都有某种形式的轻量级线程:

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

Java 也在 21 版本中引入了自己的轻量级线程实现:虚拟线程。

二、虚拟线程

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

JVM / OS 线程调度示意图

JVM / OS 线程调度示意图

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

1.物美价廉

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

因为虚拟线程非常便宜,所以虚拟线程不会被重用或需要被池化。每个任务都由其自己的虚拟线程来执行。

2.设定界限

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

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

三、代码展示

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

1.创建平台线程

创建平台线程很简单,就像使用 Runnable 创建一样:

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

随着 Project Loom 项目简化了新的并发方法,还提供了一种创建平台线程的新方法:

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

实际上,现在有一个完整的 Fluent API,因为 ofPlatform() 返回一个 Thread.Builder.OfPlatform 实例:

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

但你来这里显然不是为了学习创建“旧”线程的新方法,你想要新的东西!

2.创建虚拟线程

对于虚拟线程,同样有一个 Fluent API:

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

除了构建器方法之外,我们还可以直接使用以下命令创建虚拟线程:

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

由于所有虚拟线程始终都是守护线程,因此如果我们想在主线程上等待虚拟线程执行完毕,可以调用 join() 方法。

创建虚拟线程的另一种方法是使用 Executor 类:

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

四、总结

尽管作用域值 (JEP 446) 和结构化并发 (JEP 453) 仍然是 Java 21 中的预览功能,但虚拟线程已经成为可投入生产的成熟功能。

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

五、Java+Springboot+Vue的前后端分离项目

这是一款基于SpringBoot+Vue的前后端分离的项目,麻雀虽小,五脏俱全,开箱即用!

JNPF开发平台的前端采用Vue.js,这是一种流行的前端JavaScript框架,用于构建用户界面。Vue.js具有轻量级、可扩展性强和生态系统丰富等特点,被广泛应用于构建单页面应用程序。

后端采用SpringBoot,这是一种基于Java的开源框架,用于简化Spring应用的初始搭建以及开发过程。SpringBoot通过自动配置和约定大于配置的原则,简化了Spring应用的配置和开发。此外,JNPF还采用MyBatis-Plus作为持久层框架,它是一个功能强大的MyBatis扩展,可以大大简化数据库操作的开发。

核心功能:表单引擎、可视化引擎、BI引擎、流程引擎、权限引擎、门户引擎、大屏引擎、接口中心、物联平台

尝试自己开发一个应用!应用地址:https://www.jnpfsoft.com/?csdn

相关文章:

Java 21:虚拟线程介绍

Java 21 版本更新中最重要的功能之一就是虚拟线程 (JEP 444)。这些轻量级线程减少了编写、维护和观察高吞吐量并发应用程序所需的工作量。 正如我的许多其他文章一样,在推出新功能之前,让我们先看看 Java 21 版本更新前的现状,以便更好地了解…...

Redis-缓存穿透,缓存击穿,缓存雪崩

缓存穿透,缓存击穿,缓存雪崩 缓存穿透处理方案解决方案1 缓存空数据解决方案2 布隆过滤器 缓存击穿处理方案解决方案 1 互斥锁解决方案2 逻辑过期 缓存雪崩处理方案解决方案 1 给不同的key的过期时间设置添加一个随机值,降低同一个时段大量ke…...

如何使用Docker实现分布式Web自动化!

01、前言 顺着docker的发展,很多测试的同学也已经在测试工作上使用docker作为环境基础去进行一些自动化测试,这篇文章主要讲述在docker中使用浏览器进行自动化测试如果可以实现可视化,同时可以对浏览器进行相关的操作。 02、开篇 首先我们…...

从零开始:制作出色的产品原型图的详细教程

在设计产品的初始版本或模型时,产品原型起着非常重要的作用,可以帮助设计师和团队更好地了解产品需求和用户需求,优化和改进设计,确保设计最终满足用户的需求和期望。如果你不知道如何绘制产品原型图,绘制产品原型图的…...

美国访问学者签证如何申请加急办理?

许多中国学者梦想着前往美国深造,积累更多的学术经验和知识。然而,签证申请过程可能会变得复杂和繁琐,特别是如果你需要在紧急情况下前往美国。但别担心,本文知识人网小编将为您介绍美国访问学者签证加急办理的一些建议和步骤。 首…...

33 WEB漏洞-逻辑越权之水平垂直越权全解

目录 前言水平,垂直越权,未授权访问Pikachu-本地水平垂直越权演示(漏洞成因)墨者水平-身份认证失效漏洞实战(漏洞成因)原理越权检测-Burpsuite插件Authz安装测试(插件使用)修复防御方案 前言 越权漏洞文章分享:https://www.cnblogs.com/zhen…...

【FreeRTOS】【STM32】02 FreeRTOS 移植

基于 [野火]《FreeRTOS%20内核实现与应用开发实战—基于STM32》 正点原子《STM32F429FreeRTOS开发手册_V1.2》 准备 基础工程,例如点灯 FreeRTOS 系统源码 FreeRTOS 移植 上一章节已经说明了Free RTOS的源码文件在移植时所需要的,FreeRTOS 为我们提供…...

STM32F4X 内部FLASH使用

STM32F4X 内部FLASH使用 STM32F4X 内部FLASHSTM32F4X内部FLASH结构STM32F40X和STM32F41X内部FLASH结构STM32F42X和STM32F43X内部FLASH结构 STM32F4X内部FLASH操作例程internal_flash.hinternal_flash.cmain.c 在嵌入式开发中,经常需要实时保存一些数据。如果工程的代…...

减小windows或linux虚拟机导出ova体积大小

减小windows或linux虚拟机导出ova体积大小 删除无用的文件,比如日志或者命令,程序等;去除磁盘碎片将不用的内存空间填充为0,便于vmdk压缩。 例子: 日志文件置空: 批量置空 /sf/data/log/ 目录下的日志文…...

WPF livecharts 折线图遮挡数字问题

在WPF里使用livecharts,如果折线图或者柱状图有多个的时候,可能会出现两个数字遮挡问题,这时候要设置DataLabelsTemplate 属性。 如LineSeries设置代码如下: 第一个折线图的DataLabelsTemplate var stackPanelFactory new Fra…...

电力系统数字化升级改造之配电室无人值守

随着科技的不断进步,电力系统的数字化升级改造已成为必然趋势。其中,配电室的无人值守是其中重要的一环。 配电室是电力系统的重要组成部分,其运行状态直接影响到电力系统的稳定性和可靠性。然而,传统的配电室存在很多问题&am…...

集合Set

目录 一、去重问题 一、去重问题 题目描述&#xff1a; 小明想在学校中请一些同学一起做一项问卷调查&#xff0c;为了实验的客观性他先用计算机生成了N个1&#xff5e;1000之间的随机整数(N<1000),N是用户输入的&#xff0c;对于其中重复的数字&#xff0c;只保留一个&am…...

TCP/IP(二)导论

一 知识铺垫 以下内容参照 <<电子科技大学TCPIP协议原理>>全 ① 协议和标准 一组规则&#xff1a; 交通规则、学生上学的学生守则等;数据通信的规则,有一个专门的名称叫作协议 protocol语义&#xff1a;具体描述在通信当中,每一个信息的具体含义. 二进制bit流…...

Java之UDP,TCP的详细解析

练习四&#xff1a;文件名重复 public class UUIDTest { public static void main(String[] args) { String str UUID.randomUUID().toString().replace("-", ""); System.out.println(str);//9f15b8c356c54f55bfcb0ee3023fce8a } } public class Client…...

【总结】kubernates crd client-java 关于自定义资源的增删改查

Java model 准备 首先使用 crd.yml 和 kubernetes CRD 自动生成 Java model 类&#xff0c;这是一切的前提&#xff0c;之前在这个地方也卡了很久。如何生成在另外一个文章中已经有所记录。 使用 crd.yml 和 kubernetes CRD 自动生成 Java model 类 CustomObjectsApi 文档学习…...

蓝牙主要知识,一文概览

蓝牙知识相关 文章目录 蓝牙知识相关1.蓝牙版本的发展简史2.低功耗BLE PHY2.1 频段**2.2 BLE调制方案—GFSK**2.3 **蓝牙 LE 传输速度、功率和接收器灵敏度**2.4 **BLE 时分双工 (TDD)**3.BT主从连接过程3.1 主设备工作模式3.1.1 积木编程控制台3.2 从设备工作模式3.2.1 蓝牙遥…...

Linux 守护进程

一 何为守护进程 守护进程&#xff08; Daemon &#xff09;也称为精灵进程&#xff0c;是运行在后台的一种特殊进程&#xff0c;它独立于控制终端并且周期性 地执行某种任务或等待处理某些事情的发生&#xff0c;主要表现为以下两个特点&#xff1a; 长期运行。守护进程是一…...

自动驾驶技术的基础知识

自动驾驶技术是现代汽车工业中的一项革命性发展&#xff0c;它正在改变着我们对交通和出行的理解。本文将介绍自动驾驶技术的基础知识&#xff0c;包括其概念、历史发展、分类以及关键技术要素。 1. 自动驾驶概念 自动驾驶是一种先进的交通技术&#xff0c;它允许汽车在没有人…...

解决:yarn 无法加载文件 “C:\Users\XXXXX\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本“ 的问题

1、问题描述&#xff1a; 报错的整体代码为&#xff1a; yarn : 无法加载文件 C:\Users\admin\AppData\Roaming\npm\yarn.ps1&#xff0c;因为在此系统上禁止运行脚本 // 整体的报错代码为 &#xff1a; yarn : 无法加载文件 C:\Users\admin\AppData\Roaming\npm\yarn.ps1&…...

【JVM--StringTable字符串常量池】

文章目录 1. String 的基本特性2. 字符串拼接操作3. intern()的使用4. StringTable 的垃圾回收 1. String 的基本特性 String 声明为 final 的&#xff0c;不可被继承String 实现了 Serializable 接口&#xff1a;表示字符串是支持序列化的。String 实现了 Comparable 接口&am…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

GB/T 43887-2024 核级柔性石墨板材检测

核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标&#xff1a; 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...