SpringBoot开启虚拟线程的实现流程

 更新时间:2024年06月13日 08:20:56   作者:Java中文社群  
虚拟线程(Virtual Thread)也称协程或纤程,是一种轻量级的线程实现,与传统的线程以及操作系统级别的线程(也称为平台线程)相比,它的创建开销更小、资源利用率更高,本文给大家介绍了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()));
    }
}

最后

到此这篇关于SpringBoot开启虚拟线程的实现方法的文章就介绍到这了,更多相关SpringBoot虚拟线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringAop日志找不到方法的处理

    SpringAop日志找不到方法的处理

    这篇文章主要介绍了SpringAop日志找不到方法的处理方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot 的 web 类型推断详解

    SpringBoot 的 web 类型推断详解

    这篇文章主要介绍了SpringBoot 的 web 类型推断详解的相关资料,需要的朋友可以参考下
    2022-12-12
  • 常用数字签名算法RSA与DSA的Java程序内实现示例

    常用数字签名算法RSA与DSA的Java程序内实现示例

    这篇文章主要介绍了常用数字签名算法RSA与DSA的Java程序内实现示例,一般来说DSA算法用于签名的效率会比RSA要快,需要的朋友可以参考下
    2016-04-04
  • Java单线程ThreadLocal串值问题解决方案

    Java单线程ThreadLocal串值问题解决方案

    这篇文章主要介绍了Java单线程ThreadLocal串值问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • springboot组件初始化后的4种启动方式及常用方法

    springboot组件初始化后的4种启动方式及常用方法

    在Spring Boot中,您可以通过几种方式在组件初始化后执行启动任务,下面小编给大家分享springboot组件初始化后的4种启动方式及常用方法,感兴趣的朋友一起看看吧
    2024-06-06
  • Java实现企业微信回调配置的详细步骤与测试

    Java实现企业微信回调配置的详细步骤与测试

    这篇文章主要给大家介绍了关于Java实现企业微信回调配置的详细步骤与测试,企业微信回调是指企业微信通过HTTP POST请求将业务数据回调到指定的URL上,文中给出了详细的代码示例,需要的朋友可以参考下
    2023-09-09
  • 详解springBoot启动时找不到或无法加载主类解决办法

    详解springBoot启动时找不到或无法加载主类解决办法

    这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 详解springboot中mybatis注解形式

    详解springboot中mybatis注解形式

    在本文中小编给大家分享了关于springboot中mybatis注解形式的介绍,有兴趣的可以跟着学习下。
    2018-10-10
  • Java设计模式中的单一责任原则详解

    Java设计模式中的单一责任原则详解

    这篇文章主要介绍了Java设计模式中的单一责任原则详解,应该有且仅有一个原因引起类的变更,即单一指责原则要求一个借口或类只有一个原因引起变化,也就是一个接口或类只有一个职责,它就负责一件事情,需要的朋友可以参考下
    2023-11-11
  • 详解SpringBoot中Session超时原理说明

    详解SpringBoot中Session超时原理说明

    本篇文章主要介绍了详解SpringBoot中Session超时原理说明,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08

最新评论