Spring Boot 中的虚拟线程

在本文中,我将讨论 Spring Boot 中的虚拟线程。

在这里插入图片描述

什么是虚拟线程?

虚拟线程作为 Java 中的一项功能引入,旨在简化并发性。 Virtual threads 是 轻量级的线程,由 Java Virtual Machine 而不是操作系统管理。它们被设计为易于使用且高效,为并发编程提供了比传统 Java 线程更简单的模型。

在这里插入图片描述

  • Lightweight :与传统线程相比,虚拟线程的重量更轻。它们由 JVM 管理,许多虚拟线程可以映射到较少数量的操作系统线程。
  • Concurrency :虚拟线程旨在通过更轻松地编写可扩展和响应式应用程序来简化并发编程。
  • Thread Pool :不需要显式管理线程池。 JVM 可以根据工作负载动态调整线程数量。

在这里插入图片描述

没有执行器的虚拟线程声明方式

public static void main(String[] args) {Thread virtualThread = Thread.ofVirtual().start(() -> {System.out.println("Virtual thread running");});System.out.println("Main thread running");    }
private static void main(String[] args) {Thread virtualThread = Thread.ofVirtual().name("Virtual Thread").unstarted(() ->System.out.println("Virtual thread running"));t.start();try {virtualThread.join();} catch (InterruptedException e) {e.printStackTrace();}}

Spring Boot 中的实现

Java Version: 20
Spring Version: 3.1.0

1) pom.xml

 <dependencies><!--Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--Prometheus, Zipkin & Micrometer--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId><scope>runtime</scope><version>1.11.0</version></dependency><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-reporter-brave</artifactId><version>2.16.3</version></dependency><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId></dependency><!--Actuator & AOP--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId><version>3.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>20</source><target>20</target><compilerArgs>--enable-preview</compilerArgs></configuration></plugin></plugins>
</build>

必须确保有 Java 21 的 JVM 可用! (如果您运行的是 Java 19,则可以使用 --preview-enabled=true 运行虚拟线程。)

2) application.properties

spring.application.name=spring-vthread-servicemanagement.zipkin.tracing.endpoint=http://${ZIPKIN_HOST:localhost}:9411/api/v2/spans
management.tracing.sampling.probability=1.0
management.endpoints.web.exposure.include=info,health,prometheus,metrics
server.tomcat.mbeanregistry.enabled=true
management.metrics.tags.application=${spring.application.name}logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]

3)VThreadServiceApplication

1、创建100_000个传统Java线程并执行。
@SpringBootApplication
public class VThreadServiceApplication {public static void main(String[] args) {SpringApplication.run(VThreadServiceApplication.class, args);}@Beanpublic ApplicationRunner runner() {return args -> {var startDate = Instant.now();startThreads();var finishDate = Instant.now();System.out.println(String.format("Start Date: %s, Finish Date: %s", startDate, finishDate));System.out.println(String.format("Duration Time(Milliseconds): %s", Duration.between(startDate, finishDate).toMillis()));};}private void startThreads() throws InterruptedException {for (int i = 0; i < 100_000; i++) {int finalI = i;Thread t = new Thread(() -> System.out.println(finalI));t.start();t.join();}}}

输出:

 ..
99998
99999
Start Date: 2023-11-18T12:20:09.491114200Z, Finish Date: 2023-11-18T12:20:28.139291800Z
Duration Time(Milliseconds): 18648

Duration Time(Milliseconds): 18648

CPU使用率:

在这里插入图片描述

2.、创建100_000个虚拟Java线程并执行。

@SpringBootApplication
public class VThreadServiceApplication {public static void main(String[] args) {SpringApplication.run(VThreadServiceApplication.class, args);}@Beanpublic ApplicationRunner runner() {return args -> {var startDate = Instant.now();startVirtualThreads();var finishDate = Instant.now();System.out.println(String.format("Start Date: %s, Finish Date: %s", startDate, finishDate));System.out.println(String.format("Duration Time(Milliseconds): %s", Duration.between(startDate, finishDate).toMillis()));};}private void startVirtualThreads() throws InterruptedException {for (int i = 0; i < 100_000; i++) {int finalI = i;Thread t = Thread.ofVirtual().name(String.format("virtualThread-%s", i)).unstarted(() -> System.out.println(finalI));t.start();t.join();}}}

输出:

..
99998
99999
Start Date: 2023-11-18T12:22:14.838308900Z, Finish Date: 2023-11-18T12:22:18.588181800Z
Duration Time(Milliseconds): 3749

Duration Time(Milliseconds): 3749

CPU使用率:

在这里插入图片描述

3. 创建Http控制器
@RestController
@RequestMapping("/api/v1/threads")
@Slf4j
public class ThreadController {@GetMapping("")public String thread() throws InterruptedException {Thread.sleep(1000);var threadName = Thread.currentThread().toString();log.info(threadName);return "thread executed";}}
3.1 发送HTTP请求(传统线程)

发送 1600 请求。
并发请求数:400

命令

ab -n 1600 -c 400 host.docker.internal:8080/api/v1/threads

Response Summary

This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking host.docker.internal (be patient)
Completed 160 requests
Completed 320 requests
Completed 480 requests
Completed 640 requests
Completed 800 requests
Completed 960 requests
Completed 1120 requests
Completed 1280 requests
Completed 1440 requests
Completed 1600 requests
Finished 1600 requestsServer Software:
Server Hostname:        host.docker.internal
Server Port:            8080Document Path:          /api/v1/threads
Document Length:        15 bytesConcurrency Level:      400
Time taken for tests:   9.659 seconds
Complete requests:      1600
Failed requests:        0
Total transferred:      236800 bytes
HTML transferred:       24000 bytes
Requests per second:    165.65 [#/sec] (mean)
Time per request:       2414.722 [ms] (mean)
Time per request:       6.037 [ms] (mean, across all concurrent requests)
Transfer rate:          23.94 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        2  127  51.4    118     375
Processing:  1040 1877 258.2   1905    2438
Waiting:     1010 1755 257.0   1781    2304
Total:       1042 2004 268.9   2019    2660Percentage of the requests served within a certain time (ms)50%   201966%   203275%   204180%   204890%   254095%   260398%   263899%   2650100%   2660 (longest request)

Time taken for tests :9.659 秒

3.2发送HTTP请求(虚拟线程)

创建线程执行器
线程执行器配置

@Configuration
@Slf4j
public class ThreadExecutorConfig {@Beanpublic TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {return protocolHandler -> {log.info("Configuring " + protocolHandler + " to use VirtualThreadPerTaskExecutor");protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());};}}

发送 1600 请求。
并发请求数:400

Command 命令

ab -n 1600 -c 400 host.docker.internal:8080/api/v1/threads

Response Summary

This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking host.docker.internal (be patient)
Completed 160 requests
Completed 320 requests
Completed 480 requests
Completed 640 requests
Completed 800 requests
Completed 960 requests
Completed 1120 requests
Completed 1280 requests
Completed 1440 requests
Completed 1600 requests
Finished 1600 requestsServer Software:
Server Hostname:        host.docker.internal
Server Port:            8080Document Path:          /api/v1/threads
Document Length:        0 bytesConcurrency Level:      400
Time taken for tests:   7.912 seconds
Complete requests:      1600
Failed requests:        0
Total transferred:      211200 bytes
HTML transferred:       0 bytes
Requests per second:    202.22 [#/sec] (mean)
Time per request:       1978.077 [ms] (mean)
Time per request:       4.945 [ms] (mean, across all concurrent requests)
Transfer rate:          26.07 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        1  186  89.6    197     337
Processing:  1005 1376 251.1   1423    1855
Waiting:     1005 1198 158.2   1171    1591
Total:       1040 1562 244.2   1612    2060Percentage of the requests served within a certain time (ms)50%   161266%   166875%   169180%   172490%   190395%   199798%   203799%   2048100%   2060 (longest request)

Time taken for tests :7.912 秒

相关文档:

  • 三 分钟理解 Java 虚拟线程

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

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

相关文章

ElasticSearch:centos7安装elasticsearch7,kibana,ik中文分词器,云服务器安装elasticsearch

系统&#xff1a;centos7 elasticsearch: 7.17.16 安装目录&#xff1a;/usr/local 云服务器的安全组&#xff1a;开放 9200 和5601的端口 一、下载安装elasticsearch7.17.16 1、安装 #进入安装目录 cd /usr/local#下载elasticsearch wget https://artifacts.elastic.co/d…

Elasticsearch:在不停机的情况下优化 Elasticsearch Reindex

实现零停机、高效率和成功迁移更新的指南。更多阅读&#xff1a;Elasticsearch&#xff1a;如何轻松安全地对实时 Elasticsearch 索引 reindex 你的数据。 在使用 Elasticsearch 的时候&#xff0c;总会有需要修改索引映射的时候&#xff0c;遇到这种情况&#xff0c;我们只能做…

前端实现websocket类封装

随着Web应用程序的发展&#xff0c;越来越多的人开始利用Websocket技术来构建实时应用程序。Websocket是一种在客户端和服务器之间建立持久连接的协议。这种协议可以在一个单独的连接上实现双向通信。与HTTP请求-响应模型不同&#xff0c;Websocket允许服务器自主地向客户端发送…

想要学会JVM调优,先掌握JVM内存模型和JVM运行原理

1、前言 今天将和你一起探讨Java虚拟机&#xff08;JVM&#xff09;的性能调优。 JVM算是面试中的高频问题了&#xff0c;通常情况下总会有人问到&#xff1a;请你讲解下 JVM 的内存模型&#xff0c;JVM 的 性能调优做过&#xff1f; 2、为什么 JVM 在 Java 中如此重要 首…

利用网络教育系统构建个性化学习平台

在现代教育中&#xff0c;网络教育系统作为一种创新的学习方式&#xff0c;为学生提供了更加个性化和灵活的学习体验。在本文中&#xff0c;我们将通过简单的技术代码&#xff0c;演示如何构建一个基础的网络教育系统&#xff0c;为学生提供个性化的学习路径和资源。 1. 环境…

在Go语言中实现HTTP请求的缓存

大家好&#xff0c;我是你们可爱的编程小助手&#xff0c;今天我们要一起探讨如何使用Go语言实现HTTP请求的缓存。听起来是不是很酷&#xff1f;让我们开始吧&#xff01; 首先&#xff0c;我们要明白什么是缓存。简单来说&#xff0c;缓存就是将数据存储在内存中&#xff0c;…

Flutter配置Android和IOS允许http访问

默认情况下&#xff0c;Android和IOS只支持对https的访问&#xff0c;如果需要访问不安全的连接&#xff0c;也就是http&#xff0c;需要做以下配置。 Android 在res目录下的xml目录中(如果不存在&#xff0c;先创建xml目录)&#xff0c;创建一个xml文件network_security_con…

Appium+python自动化(三)- SDK Manager(超详解)

简介 本来宏哥一开始打算用真机做的&#xff0c;所以在前边搭建环境时候就没有下载SDK&#xff0c;但是由于许多小伙伴通过博客发短消息给宏哥留言说是没有真机&#xff0c;所以顺应民意整理一下模拟器&#xff0c;毕竟“得民心者&#xff0c;得天下”。SDK顾名思义&#xff0c…

【Linux学习笔记】Linux下nginx环境搭建

1、下载nginx 安装rpm命令: rpm ivh nginx-release.rpm。(直接使用linux命令下载wget http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm 2、设置nginx开机启动 chkconfig nginx on 3、开启nginx服务 方法一&#xff1a;service nginx…

引力魔方的基础知识总结

1.简介&#xff1a;引力魔方是投放推荐广告的渠道&#xff0c;融合了钻展和超推&#xff1b;更新升级平台之后统一叫做人群精准推广&#xff1b; 2.展位&#xff1a;包括淘宝首页、内页频道页、门户、帮派、画报等多个淘宝站内广告位 &#xff0c;每天拥有超过8亿的展现量&…

快速排序:高效分割与递归,排序领域的王者算法

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《数据结构&算法》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! &#x1f4cb; 前言 快速排序这个名词&#xff0c;快排之所以叫快排肯定是有点东西的。他在处理大规模数据集时表现及其…

怎么设置Facebook双重验证,让Facebook账号更稳定?

对于跨境电商而言&#xff0c;Facebook 账号被封是常有的事&#xff0c;原因之一可能是没有给 Facebook 设置双重验证&#xff0c;今天就和大家科普一下什么是 Facebook双重验证以及如何设置&#xff0c;另外&#xff0c;作为跨境卖家&#xff0c;我们还需要了解如何保护 Faceb…

Bert-vits2最终版Bert-vits2-2.3云端训练和推理(Colab免费GPU算力平台)

对于深度学习初学者来说&#xff0c;JupyterNoteBook的脚本运行形式显然更加友好&#xff0c;依托Python语言的跨平台特性&#xff0c;JupyterNoteBook既可以在本地线下环境运行&#xff0c;也可以在线上服务器上运行。GoogleColab作为免费GPU算力平台的执牛耳者&#xff0c;更…

视频格式网络地址转换视频到本地,获取封面、时长,其他格式转换成mp4

使用ffmpeg软件转换网络视频&#xff0c;先从官网下载对应操作系统环境的包 注意:网络地址需要是视频格式结尾&#xff0c;例如.mp4,.flv 等 官网地址&#xff1a;Download FFmpeg window包&#xff1a; linux包&#xff1a; 如果下载缓慢&#xff0c;下载迅雷安装使用…

Pycharm2023版本:Python远程调试配置详解

工欲善其事&#xff0c;必先利其器 首先你需要选择一个专业版本的pycharm&#xff0c;社区版本不支持远程配置功能&#xff0c;专业版下载地址&#xff1a;Pycharm 2023 双击程序进行安装&#xff0c;30天内免费试用&#xff0c;如果想要永久使用&#xff0c;办法你懂的&…

GBASE南大通用 GCDW阿里云计算巢:自动化部署云原生数据仓库

目前&#xff0c;GBASE南大通用已与阿里云计算巢合作&#xff0c;双方融合各自技术优势&#xff0c;助力企业用户实现云上数据仓库的自动化部署&#xff0c;让用户在云端获取数据仓库服务“更简单”&#xff0c;让用户在云端使用数据仓库服务“更便捷”&#xff0c;满足企业用户…

uniapp 安卓模拟器链接

下载genymotion 安装 配置adb路径 模拟端口设为 5307

数据库系统课程设计(高校成绩管理数据库系统的设计与实现)

目录 1、需求分析 1 1.1 数据需求描述 1 1.2 系统功能需求 3 1.3 其他性能需求 4 2、概念结构设计 4 2.1 局部E-R图 4 2.2 全局E-R图 5 2.3 优化E-R图 6 3、逻辑结构设计 6 3.1 关系模式设计 6 3.2 数据类型定义 6 3.3 关系模式的优化 8 4、物理结构设计 9 4.1 聚…

CSDN规则详解——csdn那些你不知道的事儿(点赞、评论、收藏)

文章目录 每日一句正能量前言点赞评论收藏原力等级和博客等级后记 每日一句正能量 “只有奋斗者才能成为胜利者&#xff0c;只有坚持者才能创造奇迹。” - 迈克尔乔丹 这句话来自于世界著名篮球运动员迈克尔乔丹&#xff0c;他以无与伦比的天赋和努力成为了篮球界的传奇人物。他…

基于ChatGpt,Java,SpringBoot,Vue,Milvus向量数据库的定制化聊天Web demo

customized chat GitHub - bigcyy/customized-chatgpt: 基于ChatGpt&#xff0c;Java&#xff0c;SpringBoot&#xff0c;Vue&#xff0c;Milvus向量数据库的定制化聊天Web demo 简介 基于ChatGpt&#xff0c;Java&#xff0c;SpringBoot&#xff0c;Vue&#xff0c;Milvus向…