springboot3 + java虚拟线程初体验

news2024/10/5 16:41:00

java虚拟线程介绍

虚拟线程是 Java 19 的 预览特性,估计会在Java 22被纳入 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 {

    @Bean
    public AsyncTaskExecutor applicationTaskExecutor() {
        return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());
    }

    @Bean
    public 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 用于测试
     */
    @Async
    public 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);

    @Autowired
    AsyncService 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: graceful
  tomcat.threads.max: ${TOMCAT_THREAD_NUM:800}


logging:
  level:
    com:
      demo:
        springboottest: DEBUG
#    ROOT: debug

spring:
  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.coloradmin.cn/o/1003460.html

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

相关文章

【项目分析】仿linux0.11的操作系统内核

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于《操作系统 真象还原》及各大佬博客进行的&#xff0c;每个知识点的…

linux系统移植简要过程(移植bootloader引导加载程序---移植linux内核---制作根文件系统)

一.标准linux启动过程图 对于linux启动流程分析&#xff0c;我们需要移植bootloader引导加载程序---移植linux内核---制作根文件系统镜像文件&#xff1b; 二.为什么进行系统移植&#xff1f; 对于不同的硬件平台&#xff0c;linux系统启动流程大体相同&#xff0c;但是资源需求…

Multisim14.0仿真(十二)积分放大器

一、仿真原理图&#xff1a; 二、仿真效果图&#xff1a;

道路积水监测-路面积水监测系统

随着城市化的不断发展&#xff0c;城市面临着越来越多的交通挑战&#xff0c;其中之一就是道路积水问题。道路积水不仅影响了交通安全&#xff0c;还会引发交通堵塞、交通事故和城市洪涝等问题。因此&#xff0c;开展道路积水监测是十分必要的。 城市排水、供水、燃气、供热、桥…

本地部署kubesphere集群

本地部署kubesphere集群 本文采用一主两从结构 1.前置硬件准备 准备最少3台机器&#xff0c;本人分配如下 IP&#xff1a;192.168.58.10 &#xff08;主&#xff09; 192.168.58.11 &#xff08;节点1&#xff09; 192.168.58.12 &#xff08;节点2&#xff09; 系统镜像…

3.linux的进程和服务管理

一、查看进程 1.Linux的进程介绍 1)在 LINUX 中,每个执行的程序(代码)都称为一个进程。每一个进程都分配一个ID号。 2)每一个进程,都会对应一个父进程,而这个父进程可以复制多个子进程。 3)每个进程都可能以两种方式存在的。前台与后台 4)一般系统的服务都是以后台进程的方…

icmp报文及用go实现

目录 一、概述 二、ICMP报文格式详解 2.1 什么是ICMP 2.2 ICMP报文格式 2.3 ICMP报文类型 2.4 实际报文举例 三、使用go实现icmp请求以及接收响应内容 一、概述 本文主要旨在学习icmp报文格式&#xff0c;以及通过go语言来实现ICMP发包。 二、ICMP报文格式详解 2.1 什…

Redis缓存设计与性能优化

多级缓存架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储层查不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c; 失去…

【解决】80端口被占用,无法启动apache

1.cmd输入netstat -nao,查看是什么进程占用80端口。进程显示为pid4。 2.打开任务管理器&#xff0c;详细信息选项卡&#xff0c;可以看到pid4的进程是system。 右键打开文件所在位置&#xff0c;可以看到是ntoskrnl.exe这个文件占用80端口 3.【解决方法】 &#xff08;1&am…

开源即时通讯(IM)项目OpenIM源码部署流程

由于OpenIM依赖的组件较多&#xff0c;开发者需求不一&#xff0c;导致OpenIM部署一直被人诟病&#xff0c;经过几次迭代优化&#xff0c;包括依赖的组件compose的一键部署&#xff0c;环境变量设置一次&#xff0c;全局生效&#xff0c;以及脚本重构&#xff0c;目前OpenIM部署…

淘宝直通车智能计划怎么开?

很多中小卖家不会开直通车&#xff0c;会遇到整个直通车账户亏钱又对店铺没起到正向作用的问题&#xff0c;开车目的也不明确。对于小卖家&#xff0c;店铺最缺的就是流量&#xff0c;那么如何解决流量问题&#xff1f;今天我教大家一种直通车低价引流的打法。 具体步骤&…

【halcon】halcon字符识别——OCR

前言 OCR&#xff08;Optical Character Recongnition&#xff09;光学字符识别。 halcon 的OCR&#xff0c;提供了几种方式&#xff0c;我们应该如何选择&#xff1f; 自动文本阅读器&#xff08;find_text&#xff09;手动文本阅读器&#xff08;find_text&#xff09;自己…

IDEA安装翻译插件

IDEA安装翻译插件 File->Settings->Plugins 在Marketplace中&#xff0c;找到Translation&#xff0c;点击Install 更换翻译引擎 勾选自动翻译文档 翻译 鼠标右击->点击Translate

【Vue】vue2使用vue-pdf预览pdf文件,预览多页,在线预览方式二,vue页面内预览,无需额外pdfjs包,保姆级教程

系列文章目录 【Vue】vue2预览显示quill富文本内容&#xff0c;vue-quill-editor回显页面&#xff0c;v-html回显富文本内容 【Vue】vue2项目使用swiper轮播图2023年8月21日实战保姆级教程 【Vue】vue2使用pdfjs预览pdf文件&#xff0c;在线预览方式一&#xff0c;pdfjs文件包…

手写RPC框架--11.spi机制

spi机制 spi机制a.spi介绍b.缓存spi到本地c.加载spi并将实例缓存d.统一spi加载的配置 spi机制 a.spi介绍 SPI&#xff08;Service Provider Interface&#xff09;&#xff0c;是JDK内置的一种服务提供发现机制&#xff0c;可以用来启用框架扩展和替换组件&#xff0c;主要是…

Scrum工作模式的角色和活动

​Scrum工作模式是一种敏捷软件开发方法&#xff0c;其核心是团队合作和自我组织&#xff0c;旨在通过短周期的迭代开发&#xff0c;实现快速反馈和持续改进。 Scrum工作模式包括以下角色和活动&#xff1a; 1、产品负责人&#xff08;Product Owner&#xff09;&#xff1a;…

Spring-Cloud GateWay+Vue 跨域方案汇总

文章目录 一、简介背景和概述 二、前端跨域解决方案Axios跨域CORS跨域 三、后端跨域解决方案反向代理服务器 四、Spring Cloud中的跨域解决方案Gateway网关的跨域配置 五、基于Vue和Spring Cloud的跨域整合实践**这两种配置只需配置一种即可生效&#xff08;前端or后端&#xf…

Unity和C#游戏编程入门:创建迷宫小球游戏示例

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 当涉及到Unity和C#游戏编…

电脑连接电视怎么做?学会这4个方法,轻松连接!

“我的电脑屏幕太小了&#xff0c;想将它连接到电视上看电影。有什么方法可以将电脑与电视进行连接吗&#xff1f;请教教我&#xff01;” 在今天的数字时代&#xff0c;将电脑连接到电视已经成为了常见的需求。无论是观看电影、演示文稿还是玩游戏&#xff0c;电脑连接电视可以…

蓝桥杯打卡Day7

文章目录 阶乘的末尾0整除问题 一、阶乘的末尾0IO链接 本题思路&#xff1a;由于本题需要求阶乘的末尾0&#xff0c;由于我们知道2*510可以得到一个0&#xff0c;那么我们就可以找出2的数和5的数&#xff0c;但是由于是阶乘&#xff0c;所以5的数量肯定是小于2的数量&#xf…