网易面试:SpringBoot如何开启虚拟线程?
虚拟线程(Virtual Thread)也称协程或纤程,是一种轻量级的线程实现,与传统的线程以及操作系统级别的线程(也称为平台线程)相比,它的创建开销更小、资源利用率更高,是 Java 并发编程领域的一项重要创新。
PS:虚拟线程正式发布于 Java 长期支持版(Long Term Suort,LTS)Java 21(也就是 JDK 21)。
虚拟线程是一种在 Java 虚拟机(JVM)层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此它可以减少上下文切换所带来的性能开销。
操作系统线程、普通线程(Java 线程)和虚拟线程的关系如下:

1.虚拟线程使用
虚拟线程的创建有以下 4 种方式:
- Thread.startVirtualThread(Runnable task)
- Thread.ofVirtual().unstarted(Runnable task)
- Thread.ofVirtual().factory()
- Executors.newVirtualThreadPerTaskExecutor()
具体使用如下。
1.1 startVirtualThread
创建虚拟线程,并直接启动执行任务:
// 创建并启动虚拟线程
Thread.startVirtualThread(() -> {
System.out.println("Do virtual thread.");
});
1.2 unstarted
只创建虚拟线程,但不直接启动(创建之后通过 start 启动):
// 创建虚拟线程
Thread vt = Thread.ofVirtual().unstarted(()->{
System.out.println("Do virtual thread.");
});
// 运行虚拟线程
vt.start();
1.3 factory
先创建虚拟线程工厂,然后再使用工厂创建虚拟线程,之后再调用 start() 方法进行执行:
// 创建虚拟线程工厂
ThreadFactory tf = Thread.ofVirtual().factory();
// 创建虚拟线程
Thread vt = tf.newThread(()->{
System.out.println("Do virtual thread.");
});
// 运行虚拟线程
vt.start();
1.4 newVirtualThreadPerTaskExecutor
创建虚拟线程池:
// 创建一个支持虚拟线程的线程池
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
executor.submit(()->{
System.out.println("Do virtual thread.");
});
2.虚拟线程 VS 普通线程
虚拟线程和普通线程的区别主要体现在以下几点:
- 普通线程是和操作系统的物理线程是一一对应的,而虚拟线程是 JVM 层面的逻辑线程,并不和操作系统的物理线程一一对应,它可以看作是轻量级的线程。
- 普通线程默认创建的是用户线程(而守护线程),而虚拟线程是守护线程,并且其守护线程的属性不能被修改,如果修改就会报错,如下图所示:

- 虚拟线程由 JVM 调度和使用,避免了普通线程频繁切换的性能开销,所以相比于普通的线程来说,运行效率更高。
3.SpringBoot开启虚拟线程
以最新版的 Spring Boot 3.x 为例,我们开启虚拟线程很简单,只需要在 Spring Boot 配置文件中设置“spring.threads.virtual.enabled”为“true”即可开启,以 application.yml 为例,启用虚拟线程配置如下:
spring:
threads:
virtual:
enabled: true # 启用虚拟线程
这样 Spinrg Boot 在启动 Tomcat 容器时,会使用一个虚拟线程执行器来代表原有的平台线程池。
PS:这里是虚拟线程执行器,不是虚拟线程池。
如果以上配置未生效的话,还可以通过修改 Tomcat 配置类,让其使用虚拟线程来处理每一个请求,配置代码如下:
import java.util.concurrent.Executors;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TomcatConfiguration {
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler -> {
// 使用虚拟线程来处理每一个请求
protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
};
}
}
4.异步任务开启虚拟线程
如果你想为 Spring Boot 中的异步任务 @Async 也配置虚拟线程的话,可以在 AsyncConfigurer 配置类中设置,配置代码如下:
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync // 开启异步任务
public class AsyncTaskConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return new TaskExecutorAdapter(Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name("virtual-async#", 1).factory()));
}
}
课后思考
说说虚拟线程的底层实现?有了虚拟线程后还需要虚拟线程池吗?为什么?
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。
网易面试:SpringBoot如何开启虚拟线程?的更多相关文章
- 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<支持JDK19虚拟线程的web ...
- 支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 前文链接 支持JDK19虚拟线程的web框架,之一:体 ...
- Java的虚拟线程(协程)特性开启预览阶段,多线程开发的难度将大大降低
高并发.多线程一直是Java编程中的难点,也是面试题中的要点.Java开发者也一直在尝试使用多线程来解决应用服务器的并发问题.但是多线程并不容易,为此一个新的技术出现了,这就是虚拟线程. 传统多线程的 ...
- Java19虚拟线程都来了,我正在写的线程代码会被淘汰掉吗?
Java19中引入了虚拟线程,虽然默认是关闭的,但是可以以Preview模式启用,这绝对是一个重大的更新,今天Java架构杂谈带大家开箱验货,看看这家伙实现了什么了不起的功能. 1 为什么需要虚拟线程 ...
- 面试官:Netty的线程模型可不只是主从多Reactor这么简单
笔者看来Netty的内核主要包括如下图三个部分: 其各个核心模块主要的职责如下: 内存管理 主要提高高效的内存管理,包含内存分配,内存回收. 网通通道 复制网络通信,例如实现对NIO.OIO等底层JA ...
- Java SE 19 虚拟线程
Java SE 19 虚拟线程 作者:Grey 原文地址: 博客园:Java SE 19 虚拟线程 CSDN:Java SE 19 虚拟线程 说明 虚拟线程(Virtual Threads)是在Pro ...
- 虚拟线程 - VirtualThread源码透视
前提 JDK19于2022-09-20发布GA版本,该版本提供了虚拟线程的预览功能.下载JDK19之后翻看了一下有关虚拟线程的一些源码,跟早些时候的Loom项目构建版本基本并没有很大出入,也跟第三方J ...
- 在Tomcat中启用虚拟线程特性
前提 趁着国庆前后阅读了虚拟线程相关的源码,写了一篇<虚拟线程 - VirtualThread源码透视>,里面介绍了虚拟线程的实现原理和使用示例.需要准备做一下前期准备: 安装OpenJD ...
- 支持JDK19虚拟线程的web框架,之一:体验
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于虚拟线程 随着JDK19 GA版本的发布,虚拟线程 ...
- 支持JDK19虚拟线程的web框架,之五(终篇):兴风作浪的ThreadLocal
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <支持JDK19虚拟线程的web框架>系列 ...
随机推荐
- 3分钟创建Serverless Job 定时获取新闻热搜
简介: 7月25号-8月2号工作日期间,完成场景搭建,即可获得夏日清凉小风扇(每日限量)和阿里云代金券! 云起实验室,由阿里云提供的零门槛云上实践平台.一键预置实验环境,提供详细的实验手册指导,快速体 ...
- 爱奇艺在 Dubbo 生态下的微服务架构实践
简介: 本文整理自作者于 2020 年云原生微服务大会上的分享<爱奇艺在 Dubbo 生态下的微服务架构实践>,重点介绍了爱奇艺在 Dubbo.Sentinel 等开发框架方面的使用经验以 ...
- mPaas 研发流程和线上运维介绍
简介: mPaas 研发流程和线上运维介绍 一. 背景 金融级移动开发平台 mPaaS[1](Mobile PaaS)为 App 开发.测试.运营及运维提供云到端的一站式解决方案,能有效降低技术门槛. ...
- 探秘RocketMQ源码——Series1:Producer视角看事务消息
简介: 探秘RocketMQ源码--Series1:Producer视角看事务消息 1. 前言 Apache RocketMQ作为广为人知的开源消息中间件,诞生于阿里巴巴,于2016年捐赠给了Apac ...
- 重磅 | 数据库自治服务DAS论文入选全球顶会SIGMOD,领航“数据库自动驾驶”新时代
简介: 近日,智能数据库和DAS团队研发的智能调参ResTune系统论文被SIGMOD 2021录用,SIGMOD是数据库三大顶会之首,是三大顶会中唯一一个Double Blind Review的,其 ...
- LlamaIndex 起步教程(本地模型)
提示:确保您已先按照自定义安装步骤操作. 这是一个著名的"五行代码"起步示例,使用本地 LLM(大语言模型)和嵌入模型.我们将使用 BAAI/bge-small-en-v1.5 作 ...
- dotnet 6 修复找不到 EnumeratorToEnumVariantMarshaler 问题
我将在一个 .NET Framework 项目升级到 dotnet 6 时发现构建不通过,因为原先的代码使用到了 EnumeratorToEnumVariantMarshaler 类型,在 dotne ...
- 一键关闭 Win11 系统广告「GitHub 热点速览」
不知道读者中有多少人早已对 Windows 11 系统自带的广告感到厌烦,却又不知道如何关闭它们? 虽然网上有详细的关闭教程,但是都需要逐一手动操作,不是很方便.所以,今天「GitHub 热点速览」给 ...
- SQL Server实战五:存储过程与触发器
本文介绍基于Microsoft SQL Server软件,实现数据库存储过程与触发器的创建.执行.修改与删除等操作. 目录 1 交互式创建并执行--存储过程一 2 交互式创建并执行--存储过程二 ...
- Debian(WSL)安装gprMax教程 - 适用于Windows系统
原文发布于:https://blog.zhaoxuan.site/archives/33.html: 第一时间获取最新文章请关注博客个人站:https://blog.zhaoxuan.site. 1. ...