springboot3 + java虚拟线程初体验

java虚拟线程介绍

虚拟线程是 Java 19 的 预览特性,估计会在Java 21被纳入 JDK 的正式版本中,会在2023年9月发布,目前springboot 3 已经提供了对虚拟线程的支持。

虚拟线程和平台线程主要区别在于,虚拟线程在运行周期内不依赖操作系统线程:它们与硬件脱钩,因此被称为 “虚拟”。这种解耦是由 JVM 提供的抽象层赋予的。
虚拟线程的运行成本远低于平台线程。消耗的内存要少得多。这就是为什么可以创建数百万个虚拟线程而不会出现内存不足的问题,而标准平台(或内核)线程只能创建数百个。
从理论上讲,这赋予了开发人员一种超级能力:无需依赖异步代码即可实现高性能的应用程序。

预计在不久的未来,常见的开源框架(Tomcat、Spring、Netty)都会基于虚拟线程推出新版本。

环境准备

java 20:下载地址:OpenJDK JDK 20.0.2 GA Release

idea社区版2023.2版本,目前最高支持到java 20,下载地址:下载 IntelliJ IDEA – 领先的 Java 和 Kotlin IDE

新建springboot3项目

https://start.spring.io/

在idea打开项目,最终项目文件如下图。修改项目设置:

项目文件

POM文件:修改后一定要执行一次:Maven--reload project

			<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>20</source><target>20</target><compilerArgs><arg>--enable-preview</arg></compilerArgs></configuration></plugin>

springboot启动文件

@SpringBootApplication
@EnableAsync
public class VttestApplication {public static void main(String[] args) {SpringApplication.run(VttestApplication.class, args);}
}
ThreadConfig.java
@Configuration
@ConditionalOnProperty(value = "spring.thread-executor", havingValue = "virtual")
public class ThreadConfig {@Beanpublic AsyncTaskExecutor applicationTaskExecutor() {return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());}@Beanpublic TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {return protocolHandler -> {protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());};}
}
AsyncService.java
@Service
public class AsyncService {private static final Log log = LogFactory.getLog(AsyncService.class);/**** @param countDownLatch 用于测试*/@Asyncpublic void doSomething(CountDownLatch countDownLatch) {
//        log.info(Thread.currentThread());try {Thread.sleep(50);} catch (InterruptedException ie) {ie.printStackTrace();}countDownLatch.countDown();}
}
TestController.java
@RestController
@RequestMapping("/test")
public class TestController {private static final Log log = LogFactory.getLog(TestController.class);@AutowiredAsyncService asyncService;@GetMapping("/vt")public String vt() {long start = System.currentTimeMillis();int n = 10000;CountDownLatch countDownLatch = new CountDownLatch(n);for (int i = 0; i < n; i++) {asyncService.doSomething(countDownLatch);}try {countDownLatch.await();} catch (InterruptedException ie) {ie.printStackTrace();}long end = System.currentTimeMillis();log.info("耗时:" + (end - start) + "ms");return "OK";}@GetMapping("/ds")public void doSomething() throws InterruptedException {
//        log.info("hey, I'm doing something");Thread.sleep(1000);}}

application.yml

server:port: 8092#开启优雅停机,默认immediate是立即关机shutdown: gracefultomcat.threads.max: ${TOMCAT_THREAD_NUM:800}logging:level:com:demo:springboottest: DEBUG
#    ROOT: debugspring:thread-executor: virtual  #启动虚拟线程的必须配置lifecycle:timeout-per-shutdown-phase: 30s #设置优雅停机缓冲期,最大等待时间

关键是:thread-executor: virtual #启动虚拟线程的必须配置

注释掉该行则使用普通线程,后面对比虚拟线程与普通线程性能时,可通过注释该行切换到普通线程

运行项目

通过接口 http://127.0.0.1:8092/test/vt 验证两种线程执行效率

虚拟线程执行时间:

普通线程执行时间:

这段代码执行时间相差1000倍

使用Jmeter压测  http://127.0.0.1:8092/test/ds  接口,吞吐量、响应时间均有大幅优化,并发数越高优化幅度越大。并发2000情况下的结果如下

虚拟线程

普通线程

参考文章:

在 Spring 6 中使用虚拟线程(Virtual Threads) - spring 中文网

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

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

相关文章

竞赛选题 基于机器视觉的火车票识别系统

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的火车票识别系统 该项目较为新颖&#xff0c;适合作为竞赛…

记录第一个启动代码的诞生

核使用R52&#xff0c;参考汇编模板&#xff0c;一步一步来实现。 首先是ld文件&#xff0c;这个没啥好说的&#xff0c;主要是关注给vector_table划一块地址、stack地址&#xff0c;如下&#xff1a; .text.intvec :{_vectors_start .;KEEP(*(.text.intvec))_vectors_end .;…

vscode 当中vue 全局自定义组件没有提示以及一些技巧

阅读技术文章可以查漏补缺&#xff0c;借鉴别人编码方式提高代码水平 阅读优秀项目 可以扩展业务处理能力 坚持每天阅读&#xff0c;每天学习新东西 积少成多&#xff0c;水到渠成 在写项目时候&#xff0c;我全局注册了组件&#xff0c;YhSwitch&#xff0c;但是在使用时候&am…

数值类型表示二——定点和浮点格式

目录 目录 定点小数与定点整数 定点小数原反补的转换 定点小数与定点整数的取值范围 位数扩展的区别 浮点数的格式 浮点数的规格化 规格化处理举例 例1&#xff1a; 例2&#xff1a; 特例&#xff1a; 知识点总结&#xff1a; 浮点数的IEEE754标准 移码的回顾&…

免费,开源,可批量的离线图片文字提取软件OCR

Umi-OCR 文字识别工具 免费&#xff0c;开源&#xff0c;可批量的离线OCR软件 适用于 Windows7 x64 及以上 免费&#xff1a;本项目所有代码开源&#xff0c;完全免费。方便&#xff1a;解压即用&#xff0c;离线运行&#xff0c;无需网络。批量&#xff1a;可批量导入处理图片…

企业可以自己建立大数据平台吗?有哪些好处?

随着企业的快速发展&#xff0c;企业累积了越来越多的数据&#xff0c;但管理巨量的大数据是一件非常难的事情&#xff0c;且很多数据没有充分发挥作用。因此不少企业在问&#xff0c;企业可以自己建立大数据平台吗&#xff1f;有哪些好处&#xff1f; 企业可以自己建立大数据…

sql存储引擎

-- 查询建表语句 --可以查看引擎 show create table account; -- 可以看到默认引擎 InnoDB ENGINEInnoDB -- 查看当前数据库支持得存储引擎 show engines ; # InnoDB 默认 存储引擎 # MyISAM sql早期默认 存储引擎 # MEMORY 存储在内存中 用来做临时表和缓存 存储引擎 …

Oracle,高斯创建自增序列

某些时候,需要获取到一个自增值 然后点击左下 Apply 也可以通过SQL语句执行 dual在Oracle中是张虚拟表&#xff0c;通常用于执行这样的查询 Oracle中查询语句: select 序列名.nextval from dual 在高斯数据库中:查询是 select my_sequence.nextval 不需要加form xxx 也…

文心一言插件开发全流程,ERNIE-Bot-SDK可以调用文心一言的能力

文心一言插件开发 前言插件插件是什么工作原理申请开发权限 开始第一步&#xff1a;安装python第二步&#xff1a;搭建项目manifest 描述文件&#xff1a;ai-plugin.json插件服务描述文件&#xff1a;openapi.yaml开发自己的plugin-server 第三步&#xff1a;上传插件 SDK相关链…

QT子线程或自定义类操作访问主界面UI控件的几种方法

前言 QT创建窗体工程&#xff0c;一般在MainWindow或Dialog类里可以直接通过ui指针访问控件&#xff0c;但是添加新的类后又如何访问呢&#xff0c;可以通过以下几种方式&#xff1a; 将ui指针公开后直接访问 &#xff08;1&#xff09;例如有个自己定义的类CustomCl…

Java基础篇

目录 1、Java语言有哪些特点 2、面向对象和面向过程的区别 3、八种基本数据类型的大小 4、标识符命名规则 5、Java 关键字 6、访问控制 7、instanceof 关键字的作用 8、final 关键字的作用 9、static 关键字作用 10、transient 关键字的作用 11、try catch final…

国家网络安全周 | 保障智能网联汽车产业,护航汽车数据安全

9月13日上午&#xff0c;2023年国家网络安全宣传周汽车数据安全分论坛在福州海峡国际会展中心正式举办。本次分论坛主题是“护航汽车数据安全&#xff0c;共促产业健康发展”&#xff0c;聚焦汽车数据安全、个人信息保护、密码安全、车联网安全保险等主题。 与此同时&#xff…

Golang代码漏洞扫描工具介绍——govulncheck

Golang Golang作为一款近年来最火热的服务端语言之一&#xff0c;深受广大程序员的喜爱&#xff0c;笔者最近也在用&#xff0c;特别是高并发的场景下&#xff0c;golang易用性的优势十分明显&#xff0c;但笔者这次想要介绍的并不是golang本身&#xff0c;而且golang代码的漏洞…

重数和众数问题——C语言实现

题还是很简单的&#xff0c;理清思路就可以了♪(&#xff65;ω&#xff65;)&#xff89; 问题描述&#xff1a; 给定含有n个元素的多重集合S&#xff0c;每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。 例如&#xff0c;S{1&#xff0c;2&…

基于ntchat的微信群聊同步机器人

微信群有500人上限的限制&#xff0c;建立多个群的话又有信息无法互通的不便&#xff0c;此机器人通过自动将消息转发到同一个同步组内的所有群&#xff0c;消除这一不便性&#xff0c;间接达成扩大群成员数的目的。 效果演示&#xff1a; 项目地址&#xff1a; https://gith…

Python综合案例(数据计算)

filter算子 接受一个函数&#xff0c;可用lambda快速编写&#xff1b;函数对RDD 数据逐个处理&#xff0c;得到True的保留到返回值的RDD中 """ filter成员方法的使用 """ from pyspark import SparkConf, SparkContext import os os.environ[P…

WebStorm使用Element组件库

文章目录 WebStorm使用Element组件库1. webstorm使用组件库1.1 webstorm使用vue文件1.2 首先需要安装Element Plus 2. 项目完成引入---按钮组件3. 引入日历组件4. 引入走马灯组件5. image组件5.1 懒加载滚动5.2 大图预览 6. Collapse 折叠面板手风琴组件8. Descriptions 描述列…

代理HTTP使用不当会出现哪些问题?如何正确使用代理服务?

代理HTTP是一种常见的网络代理方式&#xff0c;它为客户端和服务器之间提供中间层&#xff0c;转发上下游的请求和响应。正确使用代理HTTP可以提高采集效率、增加网络安全性、加速网络速度、保护用户隐私。但是&#xff0c;使用不当就难以达到预期的效果&#xff0c;在使用代理…

Linux使用docker安装elasticsearch-head

一、elasticsearch-head的安装启动 #下载镜像 docker pull alivv/elasticsearch-head #启动 docker run -d --name eshead -p 9100:9100 alivv/elasticsearch-head 查看日志 docker logs -f eshead 出现如下证明启动成功 浏览器访问9100端口&#xff0c;出现以下页面也说明启动…

芯科蓝牙BG27开发笔记8-片上Flash读写

目标 熟悉片上Flash的特点&#xff0c;知道如何使用&#xff0c;最好找到示例代码&#xff0c;有完整例程那是最好的 查找参考手册 除了768K的主空间&#xff0c;还包含&#xff1a; 1. USERDATA区域&#xff0c;用户定义数据&#xff0c;可以读写。大小只有1K。 2. 设备特…