虚拟线程探索与实践(JDK19)

优质博文:IT-BLOG-CN

一、简介

虚拟线程是轻量级线程,极大地减少了编写、维护和观察高吞吐量并发应用的工作量。虚拟线程是由JEP 425提出的预览功能,并在JDK 19中发布,JDK 21中最终确定虚拟线程,以下是根据开发者反馈从JDK 20中的变化:
【1】jdk21中虚拟线程始终支持线程本地变量。与在预览版本中允许的不同,现在不再可能创建不能具有线程本地变量的虚拟线程。对线程本地变量的有保障支持确保了许多现有库可以不经修改地与虚拟线程一起使用,并有助于将以任务为导向的代码迁移到使用虚拟线程。
【2】直接使用Thread.Builder API创建的虚拟线程(而不是通过Executors.newVirtualThreadPerTaskExecutor()创建的虚拟线程)现在默认情况下也会在其生命周期内进行监控,并且可以通过描述在"观察虚拟线程"部分中的新线程转储来观察。

基于协程的线程,与其他语言中的协程有相似之处,也有不同。虚拟线程是依附于主线程的,如果主线程销毁了,虚拟线程也不复存在。

二、背景

1、大量应用时同步方式,修改成异步方式投入资源大;
2、由线程池被打满引起的事故很难杜绝,很多应用将核心和非核心的应用一起交由线程池管理;

解决上面问题有两种措施:
1、NIO:优点是有成熟框架ReactorRxJava等。缺点是可读性欠缺,改造难度大;
2、虚拟线程:优点是业务侧改造成本低,无需池化,天然隔离。缺点是对nativesynchronize方法或者外部函数不友好;

三、原理

调度方式: 当前线程将任务提交给虚拟线程的时候,是一个Runnalbe状态,存放在队列中排队。任务排到第一位后,会挂在到平台线程上Platform Thread,该线程就是用户线程New Thread的线程。当任务挂载上去之后,就是一个运载线程,执行虚拟线程中的任务。当线程执行到阻塞或者IO操作的时候,它会将当前任务卸载到队列中,重新编程Runnable状态。

状态机: 与平台的线程的状态相似,我们主要看下如下两个状态的变化

RUNNING -> PARKING与普通线程一致,通常由各种block导致触发后置为PARKING状态,卸载虚拟线程,调用Continuation.yield()方法
RUNNING -> YIELDING通常为IO阻塞时置为YIELDING状态,卸载虚拟线程,调用Thread.yield

四、使用场景

计算密集型

CPU机密型: 并行开启X个任务,每个任务对5W个随机数进行排序;

结论:虚拟线程对于CPU密集型应用无优势

IO密集型

并发数CPU响应时间(ms)吞吐量
103519490
205520925
3080221296
4095261468
5099321508

结论:虚拟线程在CPU使用率达到80以后,性能有些许衰退。

结论: 相同的并发下
1、由于虚拟线程不需要大量的系统线程调度,节省了CPU的开销;
2、系统线程的大量减少,减少了CPU_Load排队的情况;
3、虚拟线程替换了dal的线程池,减少了线程数量(上面包含了JVM自身的线程和框架的线程);

使用案例代码:

CDubboClient instance = CDubboClient.getInstance();
FlightPassengerWS service = instance.getService(FlightPassengerWS.class);
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {StudentResponseType studentResponse = executor.submit( () -> service.getStudent(request).get());
}

五、死锁

synchronize同步代码块导致的死锁现象:

结论: 虚拟线程获取了连接后IO发生了卸载,当链接数耗尽,装载状态的虚拟线程由于拿不到链接被BLOCK,发生yield。由于在同步代码块中,yield失败发生绑定。导致其他获取链接的虚拟线程无运载线程可用。

解决办法: 使用ReentrantLock替换Synchronized

private final ReentranLock synLock = new ReentranLock();
synchronized(this) {}
// 替换为
synLock.lock();
try {} finally {synLock.unlock();
}

六、实践

QPS 1000+ 的项目性能监控

平台线程虚拟线程
CPU使用率(avg)20%15%
CPU_Load(max)155.5
线程数(avg)260258
时间响应(avg)118ms97ms
P99.93460ms1676ms

使用虚拟线程后,由于切换了线程,无法从HttpContext.current()获取到任何信息,需要在虚拟线程里threadlocal重新set

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/414634.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4、Redis高并发分布式锁实战

引言 在分布式系统中,保证数据的一致性和避免竞争条件是至关重要的。分布式锁是一种常用的机制,而Redis作为一款高性能的内存数据库,提供了简单而强大的分布式锁方案。本文将深入探讨如何利用Redis高并发分布式锁来解决分布式系统中的并发控…

制作一个Python聊天机器人

我们学习一下如何使用 ChatterBot 库在 Python 中创建聊天机器人,该库实现了各种机器学习算法来生成响应对话,还是挺不错的 什么是聊天机器人 聊天机器人也称为聊天机器人、机器人、人工代理等,基本上是由人工智能驱动的软件程序&#xff0…

【算法】串联所有单词的子串【滑动窗口】

题目 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。例如,如果 words ["ab","cd","ef"], 那么 "abcd…

eNSP学习——配置通过Telnet登陆系统

实验内容: 模拟公司网络场景。R1是机房的设备,办公区与机房不在同一楼层,R2和R3模拟员工主机, 通过交换机S1与R1相连。 为了方便用户的管理,需要在R1上配置Telnet使员工可以在办公区远程管理机房设备。 为…

Apache Zeppelin结合Apache Airflow使用1

Apache Zeppelin结合Apache Airflow使用1 文章目录 Apache Zeppelin结合Apache Airflow使用1前言一、安装Airflow二、使用步骤1.目标2.编写DAG2.加载、执行DAG 总结 前言 之前学了Zeppelin的使用,今天开始结合Airflow串任务。 Apache Airflow和Apache Zeppelin是两…

【Linux修行路】基本指令

目录 推荐 前言 1、重新认识操作系统 1.1 操作系统是什么? 1.2操作系统的作用 1.3 我们在计算机上的所有操作 1.4 Linux操作的特点 2、Linux基本指令 2.1 ls 指令 2.2 pwd 命令 2.3 cd 指令 2.3.1 Linux中的目录结构 2.3.2 绝对路径和相对路径 2.3.3 cd 指令 …

通过manifest清单导入项目到gitlab中

文章目录 说明使用manifest得要求Manifest 格式演示示例 说明 从gitlab 11.2引入此功能。 GitLab 允许根据manifest清单文件(如 Android 存储库使用的清单文件)导入所需的 Git 存储库。 使用manifest得要求 GitLab 必须对其数据库使用 PostgreSQL。至少…

SpiderFlow爬虫平台漏洞利用分析(CVE-2024-0195)

1. 漏洞介绍 SpiderFlow爬虫平台项目中spider-flow-web\src\main\java\org\spiderflow\controller\FunctionController.java文件的FunctionService.saveFunction函数调用了saveFunction函数,该调用了自定义函数validScript,该函数中用户能够控制 functi…

vue 解决el-table 表体数据发生变化时,未重新渲染问题

效果图父组件中数量改变后总数重新计算 子组件完整代码 <template><el-tableshow-summaryref"multipleTable"v-bind"$props"selection-change"handleSelectionChange"row-click"handleRowClick":summary-method"getSum…

【问题记录】使用命令语句从kaggle中下载数据集

从Kaggle中下载Tusimple数据集 1.服务器环境中安装kaggle 使用命令&#xff1a;pip install kaggle 2.复制下载API 具体命令如下&#xff1a; kaggle datasets download -d manideep1108/tusimple3.配置kaggle.json文件 如果直接使用命令会报错&#xff1a; root:~# kagg…

微电网优化MATLAB:火鹰优化算法(Fire Hawk Optimizer,FHO)求解微电网优化(提供MATLAB代码)

一、火鹰优化算法FHO 火鹰优化算法&#xff08;Fire Hawk Optimizer&#xff0c;FHO&#xff09;由Mahdi Azizi等人于2022年提出&#xff0c;该算法性能高效&#xff0c;思路新颖。 单目标优化&#xff1a;火鹰优化算法&#xff08;Fire Hawk Optimizer&#xff0c;FHO&#…

Python数据分析案例36——基于神经网络的AQI多步预测(空气质量预测)

案例背景 不知道大家发现了没&#xff0c;现在的神经网络做时间序列的预测都是单步预测&#xff0c;即(需要使用X的t-n期到X的t-1期的数据去预测X的t期的数据)&#xff0c;这种预测只能预测一个点&#xff0c;我需要预测X的t1期的数据就没办法了&#xff0c;有的同学说可以把预…