【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.哪些情况会造成线程的切换

前面我们已经说了线程切换的巨大代价,接下来我们就要想想,什么情况下线程会切换喃?常见的无非两种情况:

  1. 分给当前线程的时间片到了
  2. 线程阻塞了

我们分情况来讨论,首先是分给当前线程的时间片到了造成的线程切换。这类线程切换有问题吗?能被优化吗?很显然没问题,也不能去动它,因为进程和线程的出现本质上就是为了让多个程序能被交替执行,提升CPU的利用率,所以当前线程时间片到了,它就应该把CPU交出来,其它线程才有机会被执行。

至于第二种,线程阻塞引起的线程切换,就是值得我们进行优化的了。线程阻塞了,只是当前任务阻塞了,线程只是任务的载体,完全可以换个任务在上面继续执行。同理还有一种情况,就是时间片还没有用完,线程上面的任务跑完了,其实也该这样处理。

2.3.线程资源是有限的

除了上面线程切换的问题外,还有一点是值得注意的,就是线程资源是有限的,一台计算机上能开出来的线程是有上限的。

操作系统能够同时开启的线程数量是有限的主要有以下几个原因:

  1. 有限的系统资源:每个线程需要占用一定的系统资源,包括内存、CPU时间片、文件描述符等。系统的资源是有限的,因此开启过多的线程会消耗大量资源,可能导致资源耗尽或者性能下降。

  2. 调度开销:操作系统需要花费时间来管理和调度线程,包括线程的创建、销毁、切换等操作。如果线程数量过多,操作系统的调度开销会增加,降低系统的效率。

总结起来说人话就是,用来描述进程和线程的描述符(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时,使出一手虚拟线程,毫无疑问可以大大拉高系统的吞吐量。

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

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

相关文章

最新版小权云黑系统 骗子添加查询源码

小权云黑系统添加骗子,查询骗子,可添加团队后台方便审核用,在线反馈留言系统,前台提交骗子,后台需要审核才能过,后台使用光年UI界面,新增导航列表,可给网站添加导航友链,…

qt国际化多语言

vs + qt 方法 一 (1)生成.pro文件 如果报错: cannot find any qt projects to export 则执行如下: 然后重新生成 pro文件。 (2)生成ts文件 (方法1)在项目文件(xxx.pro) 文件添加: TRANSLATIONS += en.ts zh_CN.ts 然后打开cmd命令,进入项目目录,执行 l…

Spring中的循环依赖问题

目录 1、什么是Spring的循环依赖? 2、如何避免循环依赖问题? 3、Spring的三级缓存 小结 1、什么是Spring的循环依赖? Spring框架中的循环依赖问题是指两个或多个bean之间相互依赖,形成闭环,导致无法完成实例化的问…

【力扣】907.子数组的最小值之和

【力扣】907.子数组的最小值之和 文章目录 【力扣】907.子数组的最小值之和1. 题目介绍2. 解法2.1 方法一:单调栈2.2 方法二:动态规划 3. Danger参考 1. 题目介绍 给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr …

ubuntu虚拟机设置跳不出来

前几天在使用ubuntu虚拟机的时候不知道哪一步出错了,导致右上角的设置按钮失效了,怎么点设置界面都出不来。 上网查阅后,有人说是显示器的原因,但是我点设置再点左上角activity并没有显示有设置窗口。 最后找到了解决办法&#xf…

【刷题笔记】分糖果||数组||暴力通过||符合思维方式||多案例分析

分发糖果 文章目录 分发糖果1 题目描述2 题目分析2.1 寻找波峰波谷2.2 从波底往波峰攀爬!2.2 计算糖果 3 代码附录1 1 题目描述 https://leetcode.cn/problems/candy/ n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&…

Unity性能优化技巧篇

资源导入优化 随着项目越来越大,资源越来越多,有一套资源导入自动化设置很有必要,它不但可以减少你的工作量,也能更好的统一管理资源,保证资源的导入设置最优,还不会出错。 AssetPostprocessor 在Unity中…

Mo0n(月亮) MCGS触摸屏在野0day利用,强制卡死锁屏

项目:https://github.com/MartinxMax/Mo0n 后面还会不会在,我可就不知道了奥…还不收藏点赞关注 扫描存在漏洞的设备 #python3 Mo0n.py -scan 192.168.0.0/24 入侵锁屏 #python3 Mo0n.py -rhost 192.168.0.102 -lock 解锁 #python3 Mo0n.py -rhost 192.168.0.102 -unlock …

【Spring Boot】Swagger的常用注解

在Swagger的开发过程中,我们需要在Controller代码等处添加相应的注解,以便可以提高生成的接口文档的可读性为了解决这些问题,Swagger提供了很多的注解,通过这些注解,我们可以更好更清晰的描述我们的接口,包…

相机内存卡照片删除怎么恢复?没有备份可这样操作

在使用相机时,不小心删除了重要的照片可能是每位摄影爱好者的噩梦。然而,通过一些恢复方法,我们有机会挽救被删除的照片。本文将详细介绍相机内存卡照片删除恢复的方法。 图片来源于网络,如有侵权请告知 如果您误删了相机内存卡中…

项目实战——苍穹外卖(DAY10)

如果之前有改过端口号造成WebSocket无法连接的,可以看本篇文章“来单提醒”前的内容进行解决。 课程内容 Spring Task 订单状态定时处理 WebSocket 来单提醒 客户催单 功能实现:订单状态定时处理、来单提醒和客户催单 订单状态定时处理&#xff1a…

242. 有效的字母异位词

这篇文章会收录到 :算法通关村第十二关-白银挑战字符串经典题目-CSDN博客 242. 有效的字母异位词 描述 : 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t …

11【保姆级】-GO语言的struct

11【保姆级】-GO语言的struct 一、Go的面向对象1.1 说明 二、结构体2.1 结构体和结构体变量(实例)的区别和联系2.2 声明结构体 和 细节说明2.3 结构体在内存中的布局2.4 创建结构体和访问结构体的四种方式 在学习GO语言时: 先建立整体框架,然后再去抠细节…

C语言错误处理之sterror和perror函数以及断言处理方式

目录 前言 sterror函数 perror函数 断言处理方式 前言 在错误处理一中,我们解释了C语言三种处理方式中的错误号处理方式,这一篇我们在基于上一篇的基础上加入了sterror函数与perror函数,以及断言处理方式的内容...... sterror函数 包含…

fastsocket提升nginx CPS性能分析

fastsocket是针对单机网络性能优化,提升单机的cps。 提升现在单机7LB服务的性能,预计cps的性能提升一倍。 内核对nginx的性能瓶颈损耗主要在内核的三把锁。 1. accpet的全局队列的sk_lock锁 2. new_inode中的全局inode_lock锁 3. sock_alloc_file中的…

【每日一题】子数组的最小值之和

文章目录 Tag题目来源题目解读解题思路方法一:贡献法单调栈 写在最后 Tag 【贡献法】【单调栈】【数组】【2023-11-27】 题目来源 907. 子数组的最小值之和 题目解读 计算整数数组的连续子数组中最小值的和。 解题思路 本题朴素的解决思想是求出所有的连续子数组…

小航助学题库蓝桥杯题库stem选拔赛(21年1月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统(含题库答题软件账号)_程序猿下山的博客-CSDN博客 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统(含题库答题软件账号)_程序猿下山的博客-CSD…

SQL Server:流程控制语言详解

文章目录 一、批处理、脚本和变量局部变量和全局变量1、局部变量2、全局变量 二、顺序、分支和循环结构语句1、程序注释语句2、BEGIN┅END语句块3、IF┅ELSE语句4、CASE语句5、WHILE语句6、BREAK和CONTINUE语句BREAK语句CONTINUE语句 三、程序返回、屏幕显示等语句1、RETURN语句…

Python continue的用法详解与转义字符及用法

Python continue的用法详解 continue 的功能和 break 有点类似,区别是 continue 只是忽略当次循环的剩下语句,接着开始下一次循环,并不会中止循环;而 break 则是完全中止循环本身。 如下程序示范了continue 的用法: # …

工程数学笔记 | 傅里叶级数/变换的本质理解

以下内容纯属个人学习记录,难免有误,欢迎指正~ 引子 虽已工作数宰,但当因为工作的需要再次碰到傅里叶级数/变换相关的知识时是还是难免汗流浃背,读书时的痛苦的回忆涌上心头,果然曾经欠下的总归是要偿还的&#xff0c…