亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java21在spring boot中使用虛擬線程的方法

 更新時(shí)間:2025年08月23日 14:51:16   作者:不死的精靈  
本文給大家介紹Java21在spring boot中使用虛擬線程的方法,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

前置知識(shí)

虛擬線程VT(Virtual Thread)

0.環(huán)境說(shuō)明

用于驗(yàn)證的版本:

spring boot 3.1中就支持使用jdk21的虛擬線程了,但是在spring boot 3.2中可以直接通過(guò)配置的方式開(kāi)啟虛擬線程。不過(guò)本文編寫(xiě)的時(shí)候spring boot 3.3.3已經(jīng)GA了,他在3.2的基礎(chǔ)上又對(duì)虛擬線程進(jìn)行了進(jìn)一步地適配,所以本文章中的版本為3.3

在spring boot 3.2.9中配置spring.threads.virtual.enabled=true即可啟用虛擬線程

1.原理解析

開(kāi)啟了這個(gè)配置后,對(duì)我們的spring boot服務(wù)有什么影響呢?

我們?cè)趕pring boot的源碼中搜索spring.threads.virtual.enabled即可看到這個(gè)配置在spring boot中生效在了什么地方。
首先我們可以看到如下的代碼(通過(guò)代碼注釋也能看出,這個(gè)配置就是在3.2.0引入的)

/**
 * Threading of the application.
 *
 * @author Moritz Halbritter
 * @since 3.2.0
 */
public enum Threading {
	/**
	 * Platform threads. Active if virtual threads are not active.
	 */
	PLATFORM {
		@Override
		public boolean isActive(Environment environment) {
			return !VIRTUAL.isActive(environment);
		}
	},
	/**
	 * Virtual threads. Active if {@code spring.threads.virtual.enabled} is {@code true}
	 * and running on Java 21 or later.
	 */
	VIRTUAL {
		@Override
		public boolean isActive(Environment environment) {
			return environment.getProperty("spring.threads.virtual.enabled", boolean.class, false)
					&& JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.TWENTY_ONE);
		}
	};
	/**
	 * Determines whether the threading is active.
	 * @param environment the environment
	 * @return whether the threading is active
	 */
	public abstract boolean isActive(Environment environment);
}

接下來(lái)我們看一下VIRTUAL.isActive(environment)這個(gè)方法都用在了哪里(哪里用到了,就說(shuō)明哪里的虛擬線程是通過(guò)這個(gè)配置生效的)

可以看到他被用在如下的地方:

  • spring-webflux(區(qū)別于spring web的一個(gè)響應(yīng)式web開(kāi)發(fā)框架)的阻塞配置中(如果阻塞了使用什么類型的線程去進(jìn)行阻塞)
  • 注解ConditionalOnThreading的判斷條件OnThreadingCondition
    • Rabbit MQ——一個(gè)消息隊(duì)列,啟用虛擬線程則執(zhí)行configurer.setTaskExecutor(new VirtualThreadTaskExecutor("rabbit-direct-"));configurer.setTaskExecutor(new VirtualThreadTaskExecutor("rabbit-simple-"));
    • JedisConnection——一個(gè)redis客戶端,啟用虛擬線程則執(zhí)行
      SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor("redis-");
          executor.setVirtualThreads(true);
          factory.setExecutor(executor);
    • LettuceConnection——一個(gè)redis客戶端,啟用虛擬線程則執(zhí)行和Jedis類似的代碼,都是把Executor設(shè)置為一個(gè)啟用了虛擬線程的new SimpleAsyncTaskExecutor("redis-");
    • Kafka——一個(gè)消息隊(duì)列,啟用虛擬線程則執(zhí)行和Jedis類似的兩碼,把Executor設(shè)置為一個(gè)啟用了虛擬線程的new SimpleAsyncTaskExecutor("kafka-");
    • TaskExecutorConfigurations——spring boot中的任務(wù)調(diào)度器配置類,@Async(異步任務(wù)注解)所注解的方法會(huì)根據(jù)配置決定是用平臺(tái)線程執(zhí)行還是虛擬線程執(zhí)行
    • TaskSchedulingConfigurations——spring boot中定時(shí)任務(wù)配置類,@Scheduled(定時(shí)任務(wù)注解)所注解的方法會(huì)根據(jù)配置決定是用平臺(tái)線程執(zhí)行還是虛擬線程執(zhí)行
    • EmbeddedWebServerFactoryCustomizerAutoConfiguration——通常我們最關(guān)心的地方,這里定義了spring web的默認(rèn)容器tomcat的線程配置(Jetty的工作線程配置也在一起),如果開(kāi)啟了虛擬線程,則tomcat會(huì)使用虛擬線程作為執(zhí)行器(再也不用考慮tomcat默認(rèn)200線程的問(wèn)題了?。。。?/li>
  • Pulsar:一個(gè)分布式消息流平臺(tái),啟用虛擬線程則執(zhí)行containerProperties.setConsumerTaskExecutor(new VirtualThreadTaskExecutor("pulsar-consumer-"));readerContainerProperties.setReaderTaskExecutor(new VirtualThreadTaskExecutor("pulsar-reader-"));

2.spring boot的方案

通過(guò)在spring boot的源碼搜索@ConditionalOnThreading(Threading.VIRTUAL),可以看到spring boot會(huì)根據(jù)虛擬線程的開(kāi)啟與否來(lái)選擇注入不同的bean,我們以spring-data-redis為例,其具體代碼如下:

    @Bean
	@ConditionalOnMissingBean(RedisConnectionFactory.class)
	@ConditionalOnThreading(Threading.PLATFORM)
	LettuceConnectionFactory redisConnectionFactory(
			ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
			ClientResources clientResources) {
		return createConnectionFactory(builderCustomizers, clientResources);
	}
	@Bean
	@ConditionalOnMissingBean(RedisConnectionFactory.class)
	@ConditionalOnThreading(Threading.VIRTUAL)
	LettuceConnectionFactory redisConnectionFactoryVirtualThreads(
			ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
			ClientResources clientResources) {
		LettuceConnectionFactory factory = createConnectionFactory(builderCustomizers, clientResources);
		SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor("redis-");
		executor.setVirtualThreads(true);
		factory.setExecutor(executor);
		return factory;
	}

通過(guò)代碼不難看出,spring boot 3.2通過(guò)@ConditionalOnThreading注解的方式,實(shí)現(xiàn)了虛擬線程和平臺(tái)線程的動(dòng)態(tài)配置。

如果我們自己需要開(kāi)發(fā)一個(gè)能夠同時(shí)支持平臺(tái)線程和虛擬線程的sdk,可以復(fù)用這個(gè)注解。

3.注意事項(xiàng)(施工中,歡迎補(bǔ)充)

  • 使用虛擬線程本身要注意的5個(gè)點(diǎn):
    1. 大方使用“一個(gè)請(qǐng)求一個(gè)線程”的開(kāi)發(fā)方式
    2. 不需要對(duì)虛擬線程進(jìn)行池化
    3. 使用信號(hào)量控制并發(fā)
    4. 慎用ThreadLocal,使用ScopeValue(java21中還是預(yù)覽狀態(tài))代替
    5. 使用ReturnLock替代synchronized(這個(gè)問(wèn)題似乎在jdk23中會(huì)永久解決)
  • java21默認(rèn)的垃圾回收器G1和其自身的JIT編譯器C2似乎有沖突,會(huì)導(dǎo)致jvm crash?(這里不能確定,似乎在高版本jdk 21.0.7中進(jìn)行了修復(fù),但是我比較了openjdk的源碼,并沒(méi)能找到具體的改動(dòng)指向這個(gè)問(wèn)題)

到此這篇關(guān)于Java21在spring boot中使用虛擬線程的方法的文章就介紹到這了,更多相關(guān)springboot使用虛擬線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java基礎(chǔ)之教你怎么用代碼一鍵生成POJO

    Java基礎(chǔ)之教你怎么用代碼一鍵生成POJO

    這篇文章主要介紹了Java基礎(chǔ)之教你怎么用代碼一鍵生成POJO,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • java讀取證書(shū)公鑰的實(shí)現(xiàn)

    java讀取證書(shū)公鑰的實(shí)現(xiàn)

    這篇文章主要介紹了java讀取證書(shū)公鑰的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Java實(shí)現(xiàn)優(yōu)雅日期處理的方案詳解

    Java實(shí)現(xiàn)優(yōu)雅日期處理的方案詳解

    在我們的日常工作中,需要經(jīng)常處理各種格式,各種類似的的日期或者時(shí)間,下面我們就來(lái)看看如何使用java處理這樣的日期問(wèn)題吧,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • Java中使用ConcurrentHashMap實(shí)現(xiàn)線程安全的Map

    Java中使用ConcurrentHashMap實(shí)現(xiàn)線程安全的Map

    在Java中,ConcurrentHashMap是一種線程安全的哈希表,可用于實(shí)現(xiàn)多線程環(huán)境下的Map操作。它支持高并發(fā)的讀寫(xiě)操作,通過(guò)分段鎖的方式實(shí)現(xiàn)線程安全,同時(shí)提供了一些高級(jí)功能,比如迭代器弱一致性和批量操作等。ConcurrentHashMap在高并發(fā)場(chǎng)景中具有重要的應(yīng)用價(jià)值
    2023-04-04
  • Mybatis結(jié)果集映射與生命周期詳細(xì)介紹

    Mybatis結(jié)果集映射與生命周期詳細(xì)介紹

    結(jié)果集映射指的是將數(shù)據(jù)表中的字段與實(shí)體類中的屬性關(guān)聯(lián)起來(lái),這樣 MyBatis 就可以根據(jù)查詢到的數(shù)據(jù)來(lái)填充實(shí)體對(duì)象的屬性,幫助我們完成賦值操作
    2022-10-10
  • 詳解SpringBoot 快速整合MyBatis(去XML化)

    詳解SpringBoot 快速整合MyBatis(去XML化)

    本篇文章主要介紹了詳解SpringBoot 快速整合MyBatis(去XML化),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-10-10
  • SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn)

    SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn)

    微服務(wù)架構(gòu),不可避免的存在單個(gè)微服務(wù)有多個(gè)實(shí)例,這篇文章主要介紹了SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 關(guān)于@CacheEvict無(wú)法解決分頁(yè)緩存清除的解決思路

    關(guān)于@CacheEvict無(wú)法解決分頁(yè)緩存清除的解決思路

    這篇文章主要介紹了關(guān)于@CacheEvict無(wú)法解決分頁(yè)緩存清除的解決思路,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot整合Guava Cache實(shí)現(xiàn)全局緩存的示例代碼

    SpringBoot整合Guava Cache實(shí)現(xiàn)全局緩存的示例代碼

    這篇文章主要介紹了SpringBoot整合Guava Cache實(shí)現(xiàn)全局緩存,Guava Cache是Google Guava庫(kù)中的一個(gè)模塊,提供了基于內(nèi)存的本地緩存實(shí)現(xiàn),文中介紹了SpringBoot整合使用Guava Cache的具體步驟,需要的朋友可以參考下
    2024-03-03
  • Mybatis-plus 雙主鍵的實(shí)現(xiàn)示例

    Mybatis-plus 雙主鍵的實(shí)現(xiàn)示例

    本文主要介紹了Mybatis-plus 雙主鍵的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05

最新評(píng)論