【JDK21】详解虚拟线程


目录
1.概述
2.虚拟线程是为了解决哪些问题
2.1.线程切换的巨大代价
2.2.哪些情况会造成线程的切换
2.3.线程资源是有限的
3.虚拟线程
4.适用场景
1.概述
你发任你发,我用JAVA8?JDK21可能要对这句话say no了。

现在Oracle JDK是每4个版本,推出一个长期支持版本,JDK21就是前段时间发布的最新的长期支持版JDK。作为最新的长期支持版JDK,JDK21中集合了非常多的重要新特性,其中最为重要,最有意义,最吸引人的莫过于——虚拟线程。虚拟线程虽然不是JDK21才引入的,但是是在该版本中才得以稳定的,所以我们建议要用虚拟线程的话,最好还是使用JDK21。
本文将用一个清晰的思路抽丝剥茧,层层递进的去探讨:
1.虚拟线程是为了解决哪些问题
在虚拟线程出现之前,传统线程模型中线程切换存在的问题,即线程切换的代价。
然后去思考哪些情况下线程会切换?有哪些可以优化的地方?
2.虚拟线程是怎么解决这些问题的
然后是虚拟线程是怎样工作的?是怎样进行任务调度的?
3.虚拟线程的实际应用价值
虚拟线程的适用场景。
2.虚拟线程是为了解决哪些问题
2.1.线程切换的巨大代价
虚拟线程是为了解决哪些问题?自然是为了解决之前传统线程模型存在的一些问题。如果对计算机的线程模型不是很熟悉的同学博主之前有一篇文章,有兴趣可以看一下:
【进程与线程】最好懂的讲解-CSDN博客
所以传统的线程模型存在哪些问题喃?这就要从线程切换的巨大代价聊起。
先给出结论——线程的切换可能会引起CPU上下文的切换,从而造成巨大的CPU资源的浪费。接下来我们聊聊具体原因。
CPU的读写速率是要远远高于内存的读写速率的,为了配平CPU和内存之间速率的差距,CPU和内存之间存在着一个由寄存器组成的中间层,寄存器种会存放着CPU接下来要执行的指令,以及后续可能要执行到的指令以及可能要用到的数据。只有预先装载进去这部分可能要用到的东西才能抹平CPU和内存之间的速率差距,不然每次都要去内存取内容,可能是会拉低CPU的效率的。

但该预先装载哪些内容进寄存器种喃?这里遵循了程序的局部性原理。
程序的局部性原理:
程序在执行的时候呈现出局部性规律,在一段时间内,整个程序的执行仅限于程序中的某一个部分,相应的,执行所访问的存储空间也局限于某个内存区域。局部性又分为时间局部性和空间局部性。时间局部性指的是,如果程序中的某条指令一旦执行,则不久后可能会被再次执行,执行指令时访问的数据单元在不久后会被再次访问。空间局部性指的是,一旦访问了某个存储单元,不久后,其附近的存储单元也将被访问。
CPU上下文切换:
寄存器中存储着当前执行的指令、数据、以及下一条指令在内存中的地址等等事关程序正常运行的关键信息。所以寄存器中存储的内容合称为CPU的上下文。
线程切换就可能会存在这样的问题:CPU上下文中存放的是当前线程的要的东西,可能不是下个线程要用的东西。下个线程被执行的时候,可能CPU的上下文就要换一套。CPU上下文的内容本来就是来自于内存,也就是说切换上下文就是去内存中读取要的东西。CPU的读写速度是远远高于内存的读写速度的,在这个切换过程中CPU没啥事儿可干了,就会造成CPU的浪费。
2.2.哪些情况会造成线程的切换
前面我们已经说了线程切换的巨大代价,接下来我们就要想想,什么情况下线程会切换喃?常见的无非两种情况:
- 分给当前线程的时间片到了
- 线程阻塞了
我们分情况来讨论,首先是分给当前线程的时间片到了造成的线程切换。这类线程切换有问题吗?能被优化吗?很显然没问题,也不能去动它,因为进程和线程的出现本质上就是为了让多个程序能被交替执行,提升CPU的利用率,所以当前线程时间片到了,它就应该把CPU交出来,其它线程才有机会被执行。
至于第二种,线程阻塞引起的线程切换,就是值得我们进行优化的了。线程阻塞了,只是当前任务阻塞了,线程只是任务的载体,完全可以换个任务在上面继续执行。同理还有一种情况,就是时间片还没有用完,线程上面的任务跑完了,其实也该这样处理。
2.3.线程资源是有限的
除了上面线程切换的问题外,还有一点是值得注意的,就是线程资源是有限的,一台计算机上能开出来的线程是有上限的。
操作系统能够同时开启的线程数量是有限的主要有以下几个原因:
-
有限的系统资源:每个线程需要占用一定的系统资源,包括内存、CPU时间片、文件描述符等。系统的资源是有限的,因此开启过多的线程会消耗大量资源,可能导致资源耗尽或者性能下降。
-
调度开销:操作系统需要花费时间来管理和调度线程,包括线程的创建、销毁、切换等操作。如果线程数量过多,操作系统的调度开销会增加,降低系统的效率。
总结起来说人话就是,用来描述进程和线程的描述符(PCB或者TCP等)要存在内存中、内存是有限的,所以理论上线程自然是有上限的。
3.虚拟线程
前面罗嗦了这么多,总结起来无非就是计算机的线程资源是有限的,线程的切换会造成CPU资源的浪费。所以如果能复用线程资源,会提升多任务执行的效率。虚拟线程其实就是对线程资源的一种复用。
传统的JDK线程是每一条对应一条操作系统的线程,而虚拟线程是多个虚拟线程对应一条JDK的线程:

虚拟线程体系其实就是依赖于fork join pool来实现的,线程池中的每个JDK线程会对应一个任务列表,列表中会有多个虚拟线程,其实就是多个任务,由fork join pool的调度器来调度虚拟线程(任务)到各条平台线程上去。当有虚拟线程(任务)阻塞或者在时间片内提前执行完了等情况发生,调度器会去调度任务队列中的虚拟线程(任务)到这条平台线程上去继续执行:

ok,终于到虚拟线程的使用了,其实虚拟线程的使用本身反而还没有啥很多要说的。API的设计使用,当然是具有越极致的开闭性越好,所以作为线程的一个补充,虚拟线程的使用,在API层面是很简单的,和传统JDK线程的API语法几乎是一样的。
前置条件就不多说了,肯定是下载安装配置好JDK21,都在看JDK新特性的同学,这个肯定都是小问题,不赘述了。
手动开启虚拟线程:
Thread thread=Thread.ofVirtual().name("vittualThread").unstarted(new Task());
thread.start();
自动开启虚拟线程:
Thread thread=Thread.ofVirtual().name("virtualThread").start(new Task());
线程池:
ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
executorService.submit(new Task( ));
executorService.submit(new Task( ));
executorService.submit(new Task( ));
4.适用场景
虚拟线程采用协作式调度,线程主动放弃 CPU 控制权,而不是由操作系统强制切换。这种调度模型对于 IO 密集型任务非常适用,因为在等待 IO 操作完成的时候,线程可以主动让出 CPU 控制权,允许其他任务继续执行,提高了系统的吞吐量。
然而,在 CPU 密集型计算任务中,线程需要持续占用 CPU 资源进行计算,不适合频繁地放弃 CPU 控制权。虚拟线程的协作式调度可能导致任务在进行计算时频繁地让出 CPU,从而降低了计算密集型任务的执行效率。
虚拟线程对于IO密集型任务的友好,从tomcat11主动去拥抱JDK11,可见一斑:

tomcat作为一个web server,面对网络IO时,使出一手虚拟线程,毫无疑问可以大大拉高系统的吞吐量。
相关文章:
【JDK21】详解虚拟线程
目录 1.概述 2.虚拟线程是为了解决哪些问题 2.1.线程切换的巨大代价 2.2.哪些情况会造成线程的切换 2.3.线程资源是有限的 3.虚拟线程 4.适用场景 1.概述 你发任你发,我用JAVA8?JDK21可能要对这句话say no了。 现在Oracle JDK是每4个版本&#x…...
UE5 - 虚幻引擎各模块流程图
来自虚幻官方的一些资料,分享一下; 一些模块的流程图,比如动画模块: 或角色相关流程: 由于图片比较大,上传到了网络,可自取: 链接:https://pan.baidu.com/s/1BQ2KiuP08c…...
vue3实现element table缓存滚动条
背景 对于后台管理系统,数据的展示形式大多都是通过表格,常常会出现的一种场景,从表格跳到二级页面,再返回上一页时,需要缓存当前的页码和滚动条的位置,以为使用keep-alive就能实现这两种诉求,…...
flutter布局详解及代码示例(下)
布局 基本布局 GridView(二维滚动列表):比ListView多了一个方向的数据填充。ListBody(滚动列表):相比ListView,没有回收复用,简单易用。Table(表格布局)&am…...
SQL Server:流程控制语言详解
文章目录 一、批处理、脚本和变量局部变量和全局变量1、局部变量2、全局变量 二、顺序、分支和循环结构语句1、程序注释语句2、BEGIN┅END语句块3、IF┅ELSE语句4、CASE语句5、WHILE语句6、BREAK和CONTINUE语句BREAK语句CONTINUE语句 三、程序返回、屏幕显示等语句1、RETURN语句…...
2、用命令行编译Qt程序生成可执行文件exe
一、创建源文件 1、新建一个文件夹,并创建一个txt文件 2、重命名为main.cpp 3、在main.cpp中添加如下代码 #include <QApplication> #include <QDialog> #include <QLabel> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDi…...
【追求卓越08】算法--排序算法
引导 今天开始介绍我们在工作中经常遇到的算法--排序。排序算法有很多,我们主要介绍以下几种: 冒泡排序 插入排序 选择排序 归并排序 快速排序 计数排序 基数排序 桶排序 我们需要了解每一种算法的定义以及实现方式,并且掌握如何评…...
Linux fork笔试练习题
1.打印结果? #include <stdio.h> #include <unistd.h> #include <stdlib.h>int main() {int i0;for(;i<2;i){fork();printf("A\n");}exit(0); } 结果打印 A A A A A A 2.将上面的打印的\n去掉,结果如何? printf("…...
Jenkins 整合 Docker 自动化部署
Docker 安装 Jenkins 配置自动化部署 1. Docker 安装 Jenkins 1.1 拉取镜像文件 docker pull jenkins/jenkins1.2 创建挂载文件目录 mkdir -p $HOME/jenkins_home1.3 启动容器 docker run -d -p 8080:8080 -v $HOME/jenkins_home:/var/jenkins_home --name jenkins jenkin…...
竞赛选题 题目:基于大数据的用户画像分析系统 数据分析 开题
文章目录 1 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…...
selenium已知一个元素定位同级别的另一个元素
1.需求与实际情况 看下图来举例 (1)需求 想点击test22(即序号-第9行)这一行中右边的“复制”这一按钮 (2)实际情况 只能通过id或者class定位到文件名这一列的元素,而操作这一列的元素是不…...
Kotlin中 for in 是有序的吗?forEach呢?
我们要遍历一个数组、一个列表,经常会用到kotlin的 for in 语法,但是 for in 是不是有序的呢?forEach是不是有序的呢?这就需要看一下它们的本质了。 数组的 for in // 调用: val arr arrayOf(1, 2, 3) for (ele in …...
每日一练2023.11.27———连续因子【PTA】
题目链接:L1-006 连续因子 题目要求: 一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3567,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数&#…...
P8A002-CIA安全模型-配置Linux描述网络安全CIA模型之可用性案例
【预备知识】 可用性(Availability) 数据可用性是一种以使用者为中心的设计概念,易用性设计的重点在于让产品的设计能够符合使用者的习惯与需求。以互联网网站的设计为例,希望让使用者在浏览的过程中不会产生压力或感到挫折,并能让使用者在使用网站功能时,能用最少的努力…...
SpringCloudAlibaba之sentinel 流量卫兵(流控,熔断降级) ——详细讲解
目录 一、什么是sentinel 二、sentinel使用 1. sentinel dashboard的安装 2.启动 3.访问web界面 编辑 4.登录 三、sentinel 实时监控服务 1.创建项目引入依赖 2.配置 3.启动服务 4.访问dashboard界面查看服务监控 5.开发服务 6.启动进行调用 7.查看监控界面 四、senti…...
C++封装dll和lib 供C++调用
头文件interface.h #pragma once #ifndef INTERFACE_H #define INTERFACE_H #define _CRT_SECURE_NO_WARNINGS #define FENGZHUANG_API _declspec(dllexport) #include <string> namespace FengZhuang {class FENGZHUANG_API IInterface {public:static IInterface* Cre…...
ffmpeg播放器实战(播放器流程)
1.流程图 1.main窗口创建程序窗口 程序窗口构造函数执行下面内容 2.开启播放 3.开启解码 4.开启渲染 5.反馈给ui 本文福利, 免费领取C音视频学习资料包学习路线大纲、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg…...
Android 13.0 开机过滤部分通知声音(莫名其妙的通知声音)
1.概述 在13.0的系统定制开发产品的中,有时候在系统开机的时候会有一些通知的声音,但是由于系统模块太多,也搞不清楚到底是哪个模块发出的通知声音,所以就需要从通知的流程来屏蔽这些通知声音,接下来看具体怎么实现在开机的时候过滤开机声音的功能 2.开机过滤部分通知声音…...
Adversarial Attack and Defense on Graph Data: A Survey(2022 IEEE Trans)
Adversarial Attack and Defense on Graph Data: A Survey----《图数据的对抗性攻击和防御:综述》 图对抗攻击论文数据库: https://github.com/safe-graph/graph-adversarial-learning-literature 摘要 深度神经网络(DNN)已广泛应…...
css中flex两列布局(一列自适应其他固定)
问题 最近写一个布局的时候,遇到一个问题。如下图的布局。在没有图片的时候布局是正常的,如果有图片且设置了width:100%;height: 100%; 则会出现图片将自适应布局撑开的情况。 我的解决方式是让图片不缩放,图片外层再添加一个div元素。形如…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
