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

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

阿里面試:說說@Async實現(xiàn)原理?

來源: 責編: 時間:2024-07-06 07:43:56 861觀看
導讀@Async 是 Spring 3.0 提供的一個注解,用于標識某類(下的公共方法)或某方法會執(zhí)行異步調(diào)用。接下來,我們來看下 @Async 的基本使用和實現(xiàn)原理。1.基本使用@Async 基本使用可以分為以下 3 步:項目中開啟異步支持創(chuàng)建異步方

@Async 是 Spring 3.0 提供的一個注解,用于標識某類(下的公共方法)或某方法會執(zhí)行異步調(diào)用。Vc328資訊網(wǎng)——每日最新資訊28at.com

接下來,我們來看下  @Async 的基本使用和實現(xiàn)原理。Vc328資訊網(wǎng)——每日最新資訊28at.com

1.基本使用

@Async 基本使用可以分為以下 3 步:Vc328資訊網(wǎng)——每日最新資訊28at.com

  • 項目中開啟異步支持
  • 創(chuàng)建異步方法
  • 調(diào)用異步方法

1.1 開啟異步支持

以 Spring Boot 項目為例,我們首先需要在 Spring Boot 的啟動類,也就是帶有@SpringBootApplication 注解的類上添加 @EnableAsync 注解,以開啟異步方法執(zhí)行的支持,如下代碼所示:Vc328資訊網(wǎng)——每日最新資訊28at.com

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsyncpublic class MyApplication {    public static void main(String[] args) {        SpringApplication.run(MyApplication.class, args);    }}

1.2 創(chuàng)建異步方法

創(chuàng)建異步方法是在需要異步執(zhí)行的方法上添加 @Async 注解,這個方法一定是要放在被 IoC 容器管理的 Bean 中,只有被 IoC 管理的類才能實現(xiàn)異步調(diào)用,例如在帶有 @Service 注解的類中創(chuàng)建異步方法:Vc328資訊網(wǎng)——每日最新資訊28at.com

import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;@Servicepublic class AsyncService {    @Async    public void performAsyncTask() {        // 這里放置需要異步執(zhí)行的代碼        System.out.println("異步任務正在執(zhí)行,當前線程:" + Thread.currentThread().getName());    }}

1.3 調(diào)用異步方法

在其他類或方法中,通過注入這個服務類的實例來調(diào)用異步方法。注意,直接在同一個類內(nèi)部調(diào)用不會觸發(fā)異步行為,必須通過注入的實例調(diào)用,使用 new 創(chuàng)建的對象也不能進行異步方法調(diào)用,具體實現(xiàn)代碼如下:Vc328資訊網(wǎng)——每日最新資訊28at.com

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class MyController {    @Autowired    private AsyncService asyncService;    @GetMapping("/startAsync")    public String startAsyncTask() {        asyncService.performAsyncTask();        return "異步任務已啟動";    }}

2.實現(xiàn)原理

簡單來說,@Async 注解是由 AOP(面向切面)實現(xiàn)的,具體來說,它是由 AsyncAnnotationAdvisor 這個切面類來實現(xiàn)的。Vc328資訊網(wǎng)——每日最新資訊28at.com

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

在 AsyncExecutionInterceptor 中,核心方法是 getDefaultExecutor 方法,使用此方法來獲取一個線程池來執(zhí)行被 @Async 注解修飾的方法,它的實現(xiàn)源碼如下:Vc328資訊網(wǎng)——每日最新資訊28at.com

@Nullableprotected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {    Executor defaultExecutor = super.getDefaultExecutor(beanFactory);    return (Executor)(defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());}

此方法實現(xiàn)比較簡單,它是先嘗試調(diào)用父類 AsyncExecutionAspectSupport#getDefaultExecutor 方法獲取線程池,如果父類方法獲取不到線程池再用創(chuàng)建 SimpleAsyncTaskExecutor 對象作為 Async 的線程池返回。Vc328資訊網(wǎng)——每日最新資訊28at.com

而 SimpleAsyncTaskExecutor 中在執(zhí)行任務時是這樣的:Vc328資訊網(wǎng)——每日最新資訊28at.com

protected void doExecute(Runnable task) {    this.newThread(task).start();}

可以看出,在 Spring 框架中如果使用默認的 @Async 注解,它的執(zhí)行比較簡單粗暴,并沒有使用線程池,而是每次創(chuàng)建線程來執(zhí)行,所以在 Spring 框架中是不能直接使用 @Async 注解的,需要使用 @Async 注解搭配自定義的線程池,既實現(xiàn) AsyncConfigurer 接口來提供自定義的 ThreadPoolTaskExecutor 來創(chuàng)建線程池,以確保 @Async 能真正的使用線程池來執(zhí)行異步任務。Vc328資訊網(wǎng)——每日最新資訊28at.com

然而,在 Spring Boot 中,因為在框架啟動時,自動注入了 ThreadPoolTaskExecutor,如下源碼所示:Vc328資訊網(wǎng)——每日最新資訊28at.com

@ConditionalOnClass({ThreadPoolTaskExecutor.class})@AutoConfiguration@EnableConfigurationProperties({TaskExecutionProperties.class})@Import({TaskExecutorConfigurations.ThreadPoolTaskExecutorBuilderConfiguration.class, TaskExecutorConfigurations.TaskExecutorBuilderConfiguration.class, TaskExecutorConfigurations.SimpleAsyncTaskExecutorBuilderConfiguration.class, TaskExecutorConfigurations.TaskExecutorConfiguration.class})public class TaskExecutionAutoConfiguration {    public static final String APPLICATION_TASK_EXECUTOR_BEAN_NAME = "applicationTaskExecutor";    public TaskExecutionAutoConfiguration() {    }}

具體的構(gòu)建細節(jié)源碼如下:Vc328資訊網(wǎng)——每日最新資訊28at.com

@Bean@ConditionalOnMissingBean({TaskExecutorBuilder.class, ThreadPoolTaskExecutorBuilder.class})ThreadPoolTaskExecutorBuilder threadPoolTaskExecutorBuilder(TaskExecutionProperties properties, ObjectProvider<ThreadPoolTaskExecutorCustomizer> threadPoolTaskExecutorCustomizers, ObjectProvider<TaskExecutorCustomizer> taskExecutorCustomizers, ObjectProvider<TaskDecorator> taskDecorator) {    TaskExecutionProperties.Pool pool = properties.getPool();    ThreadPoolTaskExecutorBuilder builder = new ThreadPoolTaskExecutorBuilder();    builder = builder.queueCapacity(pool.getQueueCapacity());    builder = builder.corePoolSize(pool.getCoreSize());    builder = builder.maxPoolSize(pool.getMaxSize());    builder = builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout());    builder = builder.keepAlive(pool.getKeepAlive());    TaskExecutionProperties.Shutdown shutdown = properties.getShutdown();    builder = builder.awaitTermination(shutdown.isAwaitTermination());    builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());    builder = builder.threadNamePrefix(properties.getThreadNamePrefix());    Stream var10001 = threadPoolTaskExecutorCustomizers.orderedStream();    Objects.requireNonNull(var10001);    builder = builder.customizers(var10001::iterator);    builder = builder.taskDecorator((TaskDecorator)taskDecorator.getIfUnique());    builder = builder.additionalCustomizers(taskExecutorCustomizers.orderedStream().map(this::adapt).toList());    return builder;}

因此在 Spring Boot 框架中可以直接使用 @Async 注解,無需擔心它每次都會創(chuàng)建線程來執(zhí)行的問題。Vc328資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-99169-0.html阿里面試:說說@Async實現(xiàn)原理?

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

上一篇: Go語言助力安全測試:24小時內(nèi)發(fā)送5億次HTTP/1.1請求

下一篇: 為什么要限流?及常用的限流算法解析

標簽:
  • 熱門焦點
Top