当前位置:首页 > 科技  > 软件

SpringBoot3使用虚拟线程一定要小心了

来源: 责编: 时间:2024-05-11 09:21:24 421观看
导读环境:SpringBoot3.2.5 + JDK211.简介SpringBoot从3.2.0-M1版本开始支持虚拟线程。虚拟线程是JDK 21版本正式发布的一个新特性,它与平台线程的主要区别在于虚拟线程在运行周期内不依赖操作系统线程,而是与硬件脱钩,因此被

环境:SpringBoot3.2.5 + JDK21xlq28资讯网——每日最新资讯28at.com

1.简介

SpringBoot从3.2.0-M1版本开始支持虚拟线程。虚拟线程是JDK 21版本正式发布的一个新特性,它与平台线程的主要区别在于虚拟线程在运行周期内不依赖操作系统线程,而是与硬件脱钩,因此被称为“虚拟”。这种解耦是由JVM提供的抽象层赋予的,使得虚拟线程的运行成本远低于平台线程,并且可以消耗更少的内存。因此,从SpringBoot 3.2.0-M1开始,通过使用虚拟线程,提升系统的整体性能。xlq28资讯网——每日最新资讯28at.com

虚拟线程在项目中应用时你稍不注意就可能出现问题。本篇文章将要讲述的是在非Web应用的情况下使用虚拟线程出现的问题(并非BUG)。xlq28资讯网——每日最新资讯28at.com

2. 实战案例

注意:本案例是非Web应用。只要你不要引入spring-boot-starter-web模块或者下面配置后都将以非web模式下运行。xlq28资讯网——每日最新资讯28at.com

public static void main(String[] args) {  new SpringApplicationBuilder()    .sources(SpringbootNonWebApplication.class)    // 即便引入了web模块,但这里设置为非web应用    .web(WebApplicationType.NONE)    .run(args) ;}

非web应用,启动容器后并不会启动嵌入式的web server,如果你当前应用中并没有其它线程执行(非守护线程),那么程序将自动停止(启动即停止)。xlq28资讯网——每日最新资讯28at.com

图片图片xlq28资讯网——每日最新资讯28at.com

启动完后自动停止。xlq28资讯网——每日最新资讯28at.com

2.1 启动定时任务

在一个非web环境下启动定时任务:xlq28资讯网——每日最新资讯28at.com

@Componentpublic class TaskComponent {  @Scheduled(fixedRate = 3000)  public void task1() throws Exception {    System.out.printf("当前执行线程: %s%n", Thread.currentThread()) ;    // TODO 执行任务    TimeUnit.SECONDS.sleep(1) ;  }}

上面定义了每隔3s执行的定时任务(记得通过@EnableScheduling注解开启任务调用功能)。xlq28资讯网——每日最新资讯28at.com

启动服务xlq28资讯网——每日最新资讯28at.com

图片图片xlq28资讯网——每日最新资讯28at.com

程序规律的执行,每隔3s输出信息。xlq28资讯网——每日最新资讯28at.com

2.2 虚拟线程执行任务

接下来开启虚拟线程。xlq28资讯网——每日最新资讯28at.com

如果运行的是 Java 21 或更高版本,可以通过配置如下属性来启用虚拟线程。xlq28资讯网——每日最新资讯28at.com

spring:  threads:    virtual:      enabled: true

再次运行程序xlq28资讯网——每日最新资讯28at.com

图片图片xlq28资讯网——每日最新资讯28at.com

根据打印信息,执行线程确实是通过虚拟线程执行,但是仅仅启动时输出了一条信息,程序就终止了,这肯定不是我们想要的。什么原因呢?xlq28资讯网——每日最新资讯28at.com

2.3 守护线程

这是一段非常简单的代码了xlq28资讯网——每日最新资讯28at.com

Thread t = new Thread(() -> {  try {    System.out.println("start..." + System.currentTimeMillis()) ;    TimeUnit.SECONDS.sleep(5) ;  } catch (Exception e) {    e.printStackTrace() ;  }  System.out.println(" over..." + System.currentTimeMillis()) ;}) ;t.start() ;

输出结果:xlq28资讯网——每日最新资讯28at.com

start...1613150235234 over...1613150240238

程序等待3s后终止。接下来将上面Thread线程做如下配置:xlq28资讯网——每日最新资讯28at.com

// 设置为守护线程t.setDaemon(true) ;

再次执行,这次执行控制台不会有任何的输出程序就终止了。xlq28资讯网——每日最新资讯28at.com

在Java中当所有非守护线程都执行完以后,守护线程会自动终止;守护线程一般用于执行后台任务,资源清理等。xlq28资讯网——每日最新资讯28at.com

接下来通过虚拟线程执行上面的代码:xlq28资讯网——每日最新资讯28at.com

OfVirtual virtual = Thread.ofVirtual().name("Pack-") ;Thread t = virtual.start(() -> {  try {    System.out.println("start..." + System.currentTimeMillis()) ;    TimeUnit.SECONDS.sleep(5) ;  } catch (Exception e) {    e.printStackTrace() ;  }  System.out.println("over..." + System.currentTimeMillis()) ;}) ;TimeUnit.SECONDS.sleep(1) ;

等待1s后程序终止,只输出如下结果:xlq28资讯网——每日最新资讯28at.com

start...1613840844449

虚拟线程难道也是守护线程?xlq28资讯网——每日最新资讯28at.com

通过如下代码查看上面的虚拟线程是否是守护线程:xlq28资讯网——每日最新资讯28at.com

System.out.println(t.isDaemon()) ;

输出结果:xlq28资讯网——每日最新资讯28at.com

true

既然是守护线程,那么程序自动停止也就不意外了。下面是来自官方对虚拟线程与平台线程的区别:xlq28资讯网——每日最新资讯28at.com

  • 虚拟线程始终是守护线程。Thread.setDaemon(boolean) 方法无法将虚拟线程更改为非守护线程。
  • 虚拟线程的固定优先级为 Thread.NORM_PRIORITY。Thread.setPriority(int) 方法对虚拟线程不起作用。这一限制可能会在未来的版本中重新考虑。
  • 虚拟线程不是线程组的活动成员。在虚拟线程上调用 Thread.getThreadGroup() 时,会返回一个名称为 "VirtualThreads "的占位线程组。Thread.Builder API 没有定义设置虚拟线程线程组的方法。

2.4 KeepAlive虚拟线程

既然虚拟线程是守护线程,那么要如何解决上面的问题呢?在SpringBoot3.2.0-RC1版本开始为SpringApplication添加"keep-alive"属性,专门解决虚拟线程问题。xlq28资讯网——每日最新资讯28at.com

可以通过如下配置开启keepAlive。xlq28资讯网——每日最新资讯28at.com

spring:  main:    keep-alive: true

通过上面的配置后,再次运行上面的程序xlq28资讯网——每日最新资讯28at.com

图片图片xlq28资讯网——每日最新资讯28at.com

这时候程序不会退出了一直运行。✔xlq28资讯网——每日最新资讯28at.com

2.5 实现原理

当开启上面的spring.main.keep-alive=true后,springboot在启动时会注册一个监听器。xlq28资讯网——每日最新资讯28at.com

public class SpringApplication {  public ConfigurableApplicationContext run(String... args) {    // ...    prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);    // ...  }  private void prepareContext(...) {    // ...    // SpringBoot在启动时准备Environment时会自动将spring.main下的    // 属性配置绑定到当前的SpringApplication对象中(属性)。    if (this.keepAlive) {      // 添加事件监听      context.addApplicationListener(new KeepAlive());    }    // ...  }}

事件监听程序KeepAlive。xlq28资讯网——每日最新资讯28at.com

private static final class KeepAlive implements ApplicationListener<ApplicationContextEvent> {  public void onApplicationEvent(ApplicationContextEvent event) {    if (event instanceof ContextRefreshedEvent) {      // Spring上下文刷新完成      startKeepAliveThread();    }    // Spring容器在关闭时    else if (event instanceof ContextClosedEvent) {      stopKeepAliveThread();    }  }  private void startKeepAliveThread() {    // 启动异步线程,一直休眠(保证一直运行着,这样程序就不会终止了)    Thread thread = new Thread(() -> {      while (true) {        try {          Thread.sleep(Long.MAX_VALUE);        }      }    });    if (this.thread.compareAndSet(null, thread)) {      // 非守护线程      thread.setDaemon(false);      thread.setName("keep-alive");      thread.start();    }  }  private void stopKeepAliveThread() {    Thread thread = this.thread.getAndSet(null);    if (thread == null) {      return;    }    // 终止线程    thread.interrupt();  }}

SpringBoot实现逻辑还是非常简单的。xlq28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-87991-0.htmlSpringBoot3使用虚拟线程一定要小心了

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 一图看懂 React 源码中的同步更新逻辑

下一篇: Go语言整型(整数类型)的详解

标签:
  • 热门焦点
  • 6月安卓手机好评榜:魅族20 Pro蝉联冠军

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年6月1日至6月30日,仅限国内市场。第一名:魅族20 Pro好评率:95%5月份的时候魅族20 Pro就是
  • 三言两语说透设计模式的艺术-简单工厂模式

    一、写在前面工厂模式是最常见的一种创建型设计模式,通常说的工厂模式指的是工厂方法模式,是使用频率最高的工厂模式。简单工厂模式又称为静态工厂方法模式,不属于GoF 23种设计
  • 一文搞定Java NIO,以及各种奇葩流

    大家好,我是哪吒。很多朋友问我,如何才能学好IO流,对各种流的概念,云里雾里的,不求甚解。用到的时候,现百度,功能虽然实现了,但是为什么用这个?不知道。更别说效率问题了~下次再遇到,
  • 雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    来源 | 烈酒商业观察编 | 肖海林今年以来,威士忌市场开始出现了降温迹象,越来越多不断暴涨的网红威士忌也开始悄然回归市场理性。近日,LVMH集团旗下苏格兰威士忌品牌雅柏(Ardbeg
  • 2天涨粉255万,又一赛道在抖音爆火

    来源:运营研究社作者 | 张知白编辑 | 杨佩汶设计 | 晏谈梦洁这个暑期,旅游赛道彻底火了:有的「地方」火了&mdash;&mdash;贵州村超旅游收入 1 个月超过 12 亿;有的「博主」火了&m
  • OPPO K11采用全方位护眼屏:三大护眼能力减轻视觉疲劳

    日前OPPO官方宣布,全新的OPPO K11将于7月25日正式发布,将主打旗舰影像,和同档位竞品相比,其最大的卖点就是将配备索尼IMX890主摄,堪称是2000档位影像表
  • Windows 11发布,微软一改往常对老机型开放的态度

    距离 Windows 11 发布已经过去一周,在过去一周里,很多数码爱好者围绕其对 Android 应用的支持、对老机型的升级问题展开了激烈讨论。与以往不同的是,在这次大
  • 最薄的14英寸游戏笔记本电脑 Alienware X14已可以购买

    2022年1月份在国际消费电子展(CES2022)上首次亮相的Alienware新品——Alienware X14现在已经可以购买了,这款笔记本电脑被誉为世界上最薄的 14 英寸游戏笔
  • “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
Top