AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

淺析Spring中Async注解底層異步線程池原理

來源: 責編: 時間:2024-06-14 08:53:49 165觀看
導讀一、前言開發(fā)中我們經(jīng)常會用到異步方法調用,具體到代碼層面,異步方法調用的實現(xiàn)方式有很多種,比如最原始的通過實現(xiàn)Runnable接口或者繼承Thread類創(chuàng)建異步線程,然后啟動異步線程;再如,可以直接用java.util.concurrent包提供

一、前言

開發(fā)中我們經(jīng)常會用到異步方法調用,具體到代碼層面,異步方法調用的實現(xiàn)方式有很多種,比如最原始的通過實現(xiàn)Runnable接口或者繼承Thread類創(chuàng)建異步線程,然后啟動異步線程;再如,可以直接用java.util.concurrent包提供的線程池相關API實現(xiàn)異步方法調用。inC28資訊網(wǎng)——每日最新資訊28at.com

如果說可以用一行代碼快速實現(xiàn)異步方法調用,那是不是比上面方法香很多。inC28資訊網(wǎng)——每日最新資訊28at.com

Spring提供了Async注解,就可以幫助我們一行代碼搞定異步方法調用。Async注解用起來是很爽,但是如果不對其底層實現(xiàn)做深入研究,難免有時候也會心生疑慮,甚至會因使用不當,遇見一些讓人摸不著頭腦的問題。inC28資訊網(wǎng)——每日最新資訊28at.com

本文首先將對Async注解做簡單介紹,然后和大家分享一個我們項目中因Async注解使用不當?shù)木€上問題,接著再深扒Spring源碼,對Async注解底層異步線程池的實現(xiàn)原理一探究竟。inC28資訊網(wǎng)——每日最新資訊28at.com

二、Async注解簡介

inC28資訊網(wǎng)——每日最新資訊28at.com

Async注解定義源碼

inC28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片inC28資訊網(wǎng)——每日最新資訊28at.com

從源碼可以看出@Async注解定義很簡單,只需要關注兩點:inC28資訊網(wǎng)——每日最新資訊28at.com

  • Target({ElementType.TYPE, ElementType.METHOD})標志Async注解可以作用在方法和類上,作用在類上時,類的所有方法可以實現(xiàn)異步調用。
  • String value( ) default ""是唯一字段屬性,用來指定異步線程池,且該字段有缺省值。

inC28資訊網(wǎng)——每日最新資訊28at.com

Async注解異步調用實現(xiàn)原理概述inC28資訊網(wǎng)——每日最新資訊28at.com

inC28資訊網(wǎng)——每日最新資訊28at.com

在Spring框架中,Async注解的實現(xiàn)是通過AOP來實現(xiàn)的。具體來說,Async注解是由AsyncAnnotationAdvisor這個切面類來實現(xiàn)的。inC28資訊網(wǎng)——每日最新資訊28at.com

AsyncAnnotationAdvisor類是Spring框架中用于處理Async注解的切面,它會在被Async注解標識的方法被調用時,創(chuàng)建一個異步代理對象來執(zhí)行方法。這個異步代理對象會在一個新的線程中調用被@Async注解標識的方法,從而實現(xiàn)方法的異步執(zhí)行。inC28資訊網(wǎng)——每日最新資訊28at.com

在AsyncAnnotationAdvisor中,會使用AsyncExecutionInterceptor來處理Async注解。AsyncExecutionInterceptor是實現(xiàn)了MethodInterceptor接口的類,用于攔截被Async注解標識的方法的調用,并在一個新的線程中執(zhí)行這個方法。inC28資訊網(wǎng)——每日最新資訊28at.com

通過AOP的方式實現(xiàn)Async注解的異步執(zhí)行,Spring框架可以在方法調用時動態(tài)地創(chuàng)建代理對象來實現(xiàn)異步執(zhí)行,而不需要在業(yè)務代碼中顯式地創(chuàng)建新線程。inC28資訊網(wǎng)——每日最新資訊28at.com

總的來說,Async注解的實現(xiàn)是通過AOP機制來實現(xiàn)的,具體的切面類是AsyncAnnotationAdvisor,它利用AsyncExecutionInterceptor來處理被Async注解標識的方法的調用,實現(xiàn)方法的異步執(zhí)行。inC28資訊網(wǎng)——每日最新資訊28at.com

三、Async注解底層異步線程池原理探究

inC28資訊網(wǎng)——每日最新資訊28at.com

獲取Async注解線程池主流程解析

inC28資訊網(wǎng)——每日最新資訊28at.com

進入到Spring源碼Async注解AOP切面實現(xiàn)部分,我們重點剖析異步調用實現(xiàn)中線程池是怎么處理的。下圖是org.springframework.aop.interceptor.AsyncExecutionInterceptor#invoke方法的實現(xiàn),可以看出是調用determineAsyncExecutor方法獲取異步線程池。inC28資訊網(wǎng)——每日最新資訊28at.com

AsyncExecutionInterceptor#invokeAsyncExecutionInterceptor#invokeinC28資訊網(wǎng)——每日最新資訊28at.com

下圖是determineAsyncExecutor方法實現(xiàn):inC28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片inC28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片inC28資訊網(wǎng)——每日最新資訊28at.com

左圖為AsyncExecutionInterceptor#determineAsyncExecutor,右圖為AsyncExecutionAspectSupport#getExecutorQualifierinC28資訊網(wǎng)——每日最新資訊28at.com

inC28資訊網(wǎng)——每日最新資訊28at.com

從代碼實現(xiàn)中可以看到determineAsyncExecutor獲取線程池的大致流程:inC28資訊網(wǎng)——每日最新資訊28at.com

determineAsyncExecutor獲取線程池流程determineAsyncExecutor獲取線程池流程inC28資訊網(wǎng)——每日最新資訊28at.com

如果在使用Async注解時指定了自定義線程池比較好理解,如果使用Async注解時沒有指定自定義線程池,Spring是怎么處理默認線程池呢?繼續(xù)深入源碼看看Spring提供的默認線程池的實現(xiàn)。inC28資訊網(wǎng)——每日最新資訊28at.com

inC28資訊網(wǎng)——每日最新資訊28at.com

Spring是怎么為Async注解提供默認線程池的

inC28資訊網(wǎng)——每日最新資訊28at.com

Async注解默認線程池有下面兩個方法實現(xiàn):   inC28資訊網(wǎng)——每日最新資訊28at.com

  • org.springframework.aop.interceptor.AsyncExecutionInterceptor#getDefaultExecutor
  • org.springframework.aop.interceptor.AsyncExecutionAspectSupport#getDefaultExecutor

AsyncExecutionInterceptor#getDefaultExecutorAsyncExecutionInterceptor#getDefaultExecutorinC28資訊網(wǎng)——每日最新資訊28at.com

可以看出AsyncExecutionInterceptor#getDefaultExecutor方法比較簡單:先嘗試調用父類AsyncExecutionAspectSupport#getDefaultExecutor方法獲取線程池,如果父類方法獲取不到線程池再用創(chuàng)建SimpleAsyncTaskExecutor對象作為Async的線程池返回。inC28資訊網(wǎng)——每日最新資訊28at.com

AsyncExecutionAspectSupport#getDefaultExecutorAsyncExecutionAspectSupport#getDefaultExecutorinC28資訊網(wǎng)——每日最新資訊28at.com

再來看父類AsyncExecutionAspectSupport#getDefaultExecutor方法的實現(xiàn),可以看到Spring根據(jù)類型從Spring容器中獲取TaskExecutor類的實例,先記住這個關鍵點。inC28資訊網(wǎng)——每日最新資訊28at.com

我們知道,Spring根據(jù)類型獲取實例時,如果spring容器中有且只有一個指定類型的實例對象,會直接返回,否則的話,會拋出NoUniqueBeanDefinitionException異常或者NoSuchBeanDefinitionException異常。inC28資訊網(wǎng)——每日最新資訊28at.com

但是,對于Executor類型,Spring容器卻“網(wǎng)開一面”,有一個特殊處理:當從Spring容器中獲取Executor實例對象時,如果滿足@ConditionalOnMissingBean(Executor.class)條件,Spring容器會自動裝載一個ThreadPoolTaskExecutor實例對象,而ThreadPoolTaskExecutor是TaskExecutor的實現(xiàn)類。inC28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片inC28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片inC28資訊網(wǎng)——每日最新資訊28at.com

左圖為TaskExecutionAutoConfiguration,右圖為TaskExecutionPropertiesinC28資訊網(wǎng)——每日最新資訊28at.com

從TaskExecutionProperties和TaskExecutionAutoConfiguration兩個配置類我們看到Spring自動裝載的ThreadPoolTaskExecutor線程池對象的參數(shù):核心線程數(shù)=8;最大線程數(shù)=Integer.MAX_VALUE;隊列大小=Integer.MAX_VALUE。inC28資訊網(wǎng)——每日最新資訊28at.com

四、總結

現(xiàn)在Async注解線程池源碼已經(jīng)看的差不多了,下面這張圖是Spring處理Async異步線程池的流程:inC28資訊網(wǎng)——每日最新資訊28at.com

inC28資訊網(wǎng)——每日最新資訊28at.com

inC28資訊網(wǎng)——每日最新資訊28at.com

Async異步線程池獲取流程Async異步線程池獲取流程inC28資訊網(wǎng)——每日最新資訊28at.com

歸納一下:如果在使用Async注解時沒有指定自定義的線程池會出現(xiàn)以下幾種情況:inC28資訊網(wǎng)——每日最新資訊28at.com

  • 當Spring容器中有且僅有一個TaskExecutor實例時,Spring會用這個線程池來處理Async注解的異步任務,這可能會踩坑,如果這個TaskExecutor實例是第三方jar引入的,可能會出現(xiàn)很詭異的問題。
  • Spring創(chuàng)建一個核心線程數(shù)=8、最大線程數(shù)=Integer.MAX_VALUE、隊列大小=Integer.MAX_VALUE的線程池來處理Async注解的異步任務,這時候也可能會踩坑,由于線程池參數(shù)設置不合理,核心線程數(shù)=8,隊列大小過大,如果有大批量并發(fā)任務,可能會出現(xiàn)OOM。
  • Spring創(chuàng)建SimpleAsyncTaskExecutor實例來處理Async注解的異步任務,SimpleAsyncTaskExecutor不是一個好的線程池實現(xiàn)類,SimpleAsyncTaskExecutor根據(jù)需要在當前線程或者新線程中執(zhí)行異步任務。如果當前線程已經(jīng)有空閑線程可用,任務將在當前線程中執(zhí)行,否則將創(chuàng)建一個新線程來執(zhí)行任務。由于這個線程池沒有線程管理的能力,每次提交任務都實時創(chuàng)建新城,所以如果任務量大,會導致性能下降。

本文鏈接:http://www.tebozhan.com/showinfo-26-93708-0.html淺析Spring中Async注解底層異步線程池原理

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: React 19 全覽,新特性進行一次深度的體驗學習

下一篇: 618 入手三星 Galaxy Tab S9 系列 解鎖購物「新」方式

標簽:
  • 熱門焦點
Top