Java21虚拟线程实践

文章目录

  • 虚拟线程的使用
  • 什么是虚拟线程
  • 虚拟线程和协程
    • 相同之处:
    • 不同之处:
  • 总结

  就在前几天,java21正式版发布了,作为继java17之后的又一个长期支持版本 (LTS),为我们带来了很多新的特性,其中我最感兴趣的就是虚拟线程(virtual thread),相信大家对虚拟线程也很好奇。趁着空闲时间安装了jdk21来体验一把,顺便把我查到的关于java21虚拟线程相关的资料也分享下。

虚拟线程的使用

  首先来看下虚拟线程怎么使用,jdk21在Thread类中,专门提供了虚拟线程和虚拟线程工厂的创建入口,我们挨个看下。首先就是虚拟线程的创建和启动,使用lambda也就几行代码:

        Thread.ofVirtual().start(() -> {System.out.println("Hello, virtual thread!");});// 也可以指定虚拟线程的名字Thread.ofVirtual().name("virtual thread").start(() -> {System.out.println("Hello, virtual thread!");});

  Thread也提供了虚拟线程工厂,有了虚拟线程工程,我们就可以在ExecutorService中使用虚拟线程。当然Executors已经提供好了封装,我们直接调用即可:

        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {IntStream.range(1, 10_000).forEach(i -> {executor.submit(() -> {Thread.sleep(Duration.ofSeconds(0));return i;});});}

  可以看得出来,虚拟线程几乎没有啥使用门槛,那他到底和普通线程有啥区别?我在查阅了一些资料后,我的理解如下:(可能理解浅薄或者有些错误,请指正)

什么是虚拟线程

  虚拟线程是一种轻量化的线程封装,由jvm直接调度和管理。反之普通的线程其实是调用的操作系统的能力,对应的是操作系统级的线程。相对虚拟线程来说操作系统级的线程持有成本很高,而且受操作系统调度和管理的。实际在普通多线程情况下,如果出现IO阻塞,这个线程就必须得跟着阻塞,这个线程对应的操作系统就被阻塞,而他却持有大量的内存。另外,要处理大量的IO就得新建更多线程,而大量的线程会在操作系统切换时因上下文切换导致大量的CPU被浪费。

  如果我们能在某个普通线程在等待IO返回的情况下,让其运行其他的任务,是不是就可以用少量的线程处理大量的IO?思路很美好,那具体怎么实施呢!在计算机科学领域,解决问题最简单的方式就是加一层,比如操作系统中,代码访问内存中间就有一层虚拟内存,如果代码到线程中间加一层虚拟线程,每个虚拟线程只有在真正需要CPU运行的时候,才会被映射到真正的线程上去运行,而IO阻塞时会换其他非阻塞的虚拟线程上来,这样就不需要创建大量的线程了,而虚拟线程只需要持有少量的上下文信息即可。

  这种实现方式带来了很多优势,比如:

  • 轻量级:虚拟线程占用内存更少,创建和切换代价更低。
  • 支持异步:虚拟线程支持异步非阻塞编程模型。
  • 扩展性好:可以在少量线程上运行大量虚拟线程。
  • 无上下文切换:协程在同一线程中运行,没有线程上下文切换。

虚拟线程和协程

  Java21实际上在实现虚拟线程时,兼容了普通线程(不确定是否完全兼容),像ThreadLocal、Semaphore之类的工具完全可以在虚拟线程中使用,基本上大部分使用线程的地方应该都可以替换成虚拟线程,也就是说以后可以肆无忌惮创建虚拟线程而不用担心过多创建线程了。以上的内容看起来很像是go或者python中的协程,但在medium上看到一篇文章,解释了Java中的虚拟线程和协程之间的异同,摘抄下来方便大家更深入理解,如果有兴趣也可以去看原文。

相同之处:

  • 虚拟线程和协程都很轻量级,它们的创建和销毁开销小于传统的操作系统线程。
  • 虚拟线程和协程都可以通过暂停和恢复在线程之间切换,从而避免线程上下文切换的开销。
  • 虚拟线程和协程都可以以异步和非阻塞的方式处理任务,提高应用程序性能和响应速度。

不同之处:

  • 虚拟线程在JVM级别实现,而协程在语言级别实现。因此,虚拟线程的实现可以用于任何支持JVM的语言,而协程的实现需要特定编程语言的支持。
  • 虚拟线程是协程的基于线程的实现,因此可以使用线程相关的API,如ThreadLocal,Lock和Semaphore。协程不依赖于线程,通常需要特定的异步编程框架和API。
  • 虚拟线程的调度由JVM管理,而协程的调度由编程语言或异步编程框架管理。因此,虚拟线程可以更好地与其他线程合作,而协程更适合处理异步任务。

总结

  有了虚拟线程,我们可以用虚拟线程替换许多使用线程的场景,任何需要异步或者多线程运行的情况下,我们都直接直接扔给虚拟线程去运行,丝毫不用顾虑的过度创建线程的问题。虚拟线程是否能完全替代普通线程,这点肯定是不可能的,比较很多时候还是需要操作系统去做任务调度的,而目前操作系统最小的调度单位依旧是线程。

  总之,Java21正式推迟了虚拟线程,我相信在很多高IO的场景下肯定可以提升性能的,至于具体能提升多少,还是有待于具体数据的。 最后用两句老梗来结束本篇文章。

他发任他发,我用Java8。
Java21这么好用的功能,希望在有生之年能在生产环境用上。

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

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

相关文章

【线性代数】

0、线性代数的本质往往被淹没在计算的海洋中,无人问津! 1、什么是向量? 向量是带方向的箭头,向量是坐标。 2、向量的线性组合 两个向量不共线,即线性无关;两个向量共线,即线性相关。 两个不…

关于地址存放的例题

unsigned int a 0x1234; unsigned char b *(unsigned char*)&a; 上面代码大端存储和小端存储的值分别是多少? 大端存储的是把高位地址存放在低位地址处,低位存放到高位。小端是高位存放在高位,低位在低位。因为a是整型,所…

GraphQL基础知识与Spring for GraphQL使用教程

文章目录 1、数据类型1.1、标量类型1.2. 高级数据类型 基本操作2、Spring for GraphQL实例2.1、项目目录2.2、数据库表2.3、GraphQL的schema.graphql2.4、Java代码 3、运行效果3.1、添加用户3.2、添加日志3.3、查询所有日志3.4、查询指定用户日志3.5、数据订阅 4、总结 GraphQL…

C 语言简单入门

C 语言发展历史|标准 1972年,丹尼斯里奇(Dennis Ritch)和肯汤普逊(Ken Tompson)在贝尔实验室开发 UNIX 操作系统时基于 B 语言设计出 C 语言。 1987年,布莱恩柯林汉(Brian Kernighan&#xff…

数据库基础理论

什么是数据库? 数据:描述事物的符号记录,可以是数字、文字、图形、图像、声音、语言等,数据有多种形式,他们都是可以经过数字化后存入计算机。 数据库:存储数据的仓库,是长期存放在计算机内、…

世界前沿技术发展报告2023《世界信息技术发展报告》(三)量子信息技术

(三)量子信息技术 1. 概述2. 量子计算2.1 阿里巴巴达摩院成功研制两比特量子芯片,单比特操控精度超99.97%2.2 加拿大Xanadu公司开发出可编程光量子计算机2.3 美国英伟达公司为经典-量子混合计算推出开发架构2.4 日本国家自然科学研究所开发出…

SpringBoot实战

ISBN: 978-7-115-43314-5 作者:【美】Craig Walls 译者:丁雪丰 页数:209页 阅读时间:2022-12-27 推荐指数:★★★☆☆ 阅读本书还是要有一定的基础的,如果想要入门级还是不行, 建议入门级可以看…

python+nodejs+php+springboot+vue 法律知识分享科普系统平台

在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 要想实现法律知…

数字图像基础,数字图像处理中的基础内容(数字图像处理概念 P2)

文章目录 人类视觉系统构造数字图像生成采样和量化像素之间的基本关系 人类视觉系统构造 锥状体:明亮的视野杆状体:微光或暗视野图像成像原理:类似照相机亮度适应现象:人的视觉不能同时在一个范围内工作同时对比现象:…

el-select的某一项选中后显示id

环境: vue3element-plus 今天在使用elementui的下拉组件的时候发现有一个选项在选中后显示的是id.找了会没看到问题,后来想到会不会是没有设置key的原因(之前看到说vue3可以不用设置key),果然加上key就可以了

README

title: “README” createTime: 2022-01-04T20:48:4008:00 updateTime: 2022-01-04T20:48:4008:00 draft: false author: “name” tags: [“shell”] categories: [“hadoop”] description: “测试的” hadoop 相关技术 获取某个application的 日志 yarn logs -application…

变量、因子、缺失值、类型转换、剔除多余变量、随机抽样、用R使用SQL、trim、na.rm=TRUE、数据标准化应用

变量:名义型、有序型、连续型变量 名义型:普通事件类型,如糖尿病I型和糖尿病II型。 有序型:有顺序的事件类型,如一年级、二年级和三年级。 连续型:表示有顺序的数量,如年龄。 因子:…

基于Python+Django的热门旅游景点数据分析系统的设计与实现(源码+lw+部署文档+讲解等)

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

C++项目:仿muduo库实现高性能高并发服务器

文章目录 一、实现目标二、前置知识(一)HTTP服务器1.概念 (二)Reactor模型:1.概念2.分类(1)单Reactor单线程:单I/O多路复用业务处理。(2)单Reactor多线程&…

Docker--network命令的用法

原文网址:Docker--network命令的用法_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Docker的network网络命令的用法。 官网网址 docker network | Docker Documentation 命令概述 所有命令 命令名称 说明 docker network connect 将容器连接到网络 dock…

软件设计中常见的设计模式

以下是常见的设计模式,并且给出了应用场景: 工厂模式(Factory Pattern):用于创建对象,隐藏了具体对象的创建细节,客户端只需要通过工厂接口获取对象即可。应用场景包括:当需要根据不…

ultraEdit正则匹配多行(xml用)

在ultraEdit中&#xff0c;我想选取<channel到</channel>之间的多行&#xff08;进行删除&#xff09;。在perl模式下&#xff0c;命令为“<channel[\s\S]?</channel>”。下面是xml文件&#xff1a; <!--This XML file does not appear to have any sty…

Golang结构体按某一成员变量排序

结构体排序使用sort包中的sort.SliceStable() 函数。该函数需要传入一个结构体数组参数和一个匿名函数&#xff08;排序方式&#xff09; e.g. type inte struct {l, r int } //调用排序函数&#xff0c;按inte中l从小到大的方式排序 sort.SliceStable(intes, func(i, j int) …

数据结构 | 顺序表

考虑因素 插入 存储容量够吗 &#xff08;n<list_size&#xff09;插入位置正确吗(i>1&&i<n1)要插入位置后的元素后移&#xff08;循环处理&#xff09;&#xff08;An先移动&#xff09; An-Ai1插入元素表长1 删除 判断是否空&#xff0c;删除位置是否正确元…

在北京多有钱能称为富

背景 首先声明&#xff0c;此讨论仅限个人的观点&#xff0c;因为我本身不富嘛&#xff0c;所以想法应该非常局限。 举个栗子 富二代问我朋友&#xff0c;100~1000w之间&#xff0c;推荐一款车&#xff1f; 一开始听到这个问题的时候&#xff0c;有被唬住&#xff0c;觉得预…