成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說(shuō)說(shuō)@Async的底層實(shí)現(xiàn)?

開發(fā) 前端
@Async 是 Spring 3.0 提供的一個(gè)注解,用于標(biāo)識(shí)某類(下的公共方法)或某方法會(huì)執(zhí)行異步調(diào)用。接下來(lái),我們來(lái)看下 ?@Async 的基本使用和實(shí)現(xiàn)原理。

@Async 是 Spring 3.0 提供的一個(gè)注解,用于標(biāo)識(shí)某類(下的公共方法)或某方法會(huì)執(zhí)行異步調(diào)用。

接下來(lái),我們來(lái)看下  @Async 的基本使用和實(shí)現(xiàn)原理。

1.基本使用

@Async 基本使用可以分為以下 3 步:

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

1.1 開啟異步支持

以 Spring Boot 項(xiàng)目為例,我們首先需要在 Spring Boot 的啟動(dòng)類,也就是帶有@SpringBootApplication 注解的類上添加 @EnableAsync 注解,以開啟異步方法執(zhí)行的支持,如下代碼所示:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

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

創(chuàng)建異步方法是在需要異步執(zhí)行的方法上添加 @Async 注解,這個(gè)方法一定是要放在被 IoC 容器管理的 Bean 中,只有被 IoC 管理的類才能實(shí)現(xiàn)異步調(diào)用,例如在帶有 @Service 注解的類中創(chuàng)建異步方法:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {

    @Async
    public void performAsyncTask() {
        // 這里放置需要異步執(zhí)行的代碼
        System.out.println("異步任務(wù)正在執(zhí)行,當(dāng)前線程:" + Thread.currentThread().getName());
    }
}

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

在其他類或方法中,通過(guò)注入這個(gè)服務(wù)類的實(shí)例來(lái)調(diào)用異步方法。注意,直接在同一個(gè)類內(nèi)部調(diào)用不會(huì)觸發(fā)異步行為,必須通過(guò)注入的實(shí)例調(diào)用,使用 new 創(chuàng)建的對(duì)象也不能進(jìn)行異步方法調(diào)用,具體實(shí)現(xiàn)代碼如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
publicclass MyController {

    @Autowired
    private AsyncService asyncService;

    @GetMapping("/startAsync")
    public String startAsyncTask() {
        asyncService.performAsyncTask();
        return"異步任務(wù)已啟動(dòng)";
    }
}

2.實(shí)現(xiàn)原理

簡(jiǎn)單來(lái)說(shuō),@Async 注解是由 AOP(面向切面)實(shí)現(xiàn)的,具體來(lái)說(shuō),它是由 AsyncAnnotationAdvisor 這個(gè)切面類來(lái)實(shí)現(xiàn)的。

在 AsyncAnnotationAdvisor 中,會(huì)使用 AsyncExecutionInterceptor 來(lái)處理 @Async 注解,它會(huì)在被 @Async 注解標(biāo)識(shí)的方法被調(diào)用時(shí),創(chuàng)建一個(gè)異步代理對(duì)象來(lái)執(zhí)行方法。這個(gè)異步代理對(duì)象會(huì)在一個(gè)新的線程中調(diào)用被 @Async 注解標(biāo)識(shí)的方法,從而實(shí)現(xiàn)方法的異步執(zhí)行。

在 AsyncExecutionInterceptor 中,核心方法是 getDefaultExecutor 方法,使用此方法來(lái)獲取一個(gè)線程池來(lái)執(zhí)行被 @Async 注解修飾的方法,它的實(shí)現(xiàn)源碼如下:

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

此方法實(shí)現(xiàn)比較簡(jiǎn)單,它是先嘗試調(diào)用父類 AsyncExecutionAspectSupport#getDefaultExecutor 方法獲取線程池,如果父類方法獲取不到線程池再用創(chuàng)建 SimpleAsyncTaskExecutor 對(duì)象作為 Async 的線程池返回。

而 SimpleAsyncTaskExecutor 中在執(zhí)行任務(wù)時(shí)是這樣的:

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

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

然而,在 Spring Boot 中,因?yàn)樵诳蚣軉?dòng)時(shí),自動(dòng)注入了 ThreadPoolTaskExecutor,如下源碼所示:

@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)建細(xì)節(jié)源碼如下:

@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 注解,無(wú)需擔(dān)心它每次都會(huì)創(chuàng)建線程來(lái)執(zhí)行的問(wèn)題

責(zé)任編輯:武曉燕 來(lái)源: 磊哥和java
相關(guān)推薦

2024-08-22 10:39:50

@Async注解代理

2024-02-29 16:49:20

volatileJava并發(fā)編程

2024-08-29 16:30:27

2024-03-14 14:56:22

反射Java數(shù)據(jù)庫(kù)連接

2024-03-06 15:38:06

Spring微服務(wù)架構(gòu)擴(kuò)展組件

2020-07-02 07:52:11

RedisHash映射

2024-03-05 10:33:39

AOPSpring編程

2024-09-04 17:35:09

2024-07-31 08:28:37

DMAIOMMap

2024-12-06 07:00:00

2022-06-15 15:14:17

Java公平鎖非公平鎖

2024-03-22 06:56:24

零拷貝技術(shù)數(shù)據(jù)傳輸數(shù)據(jù)拷貝

2024-09-20 08:36:43

零拷貝數(shù)據(jù)傳輸DMA

2024-08-12 17:36:54

2024-06-04 09:02:03

2025-02-28 00:00:00

2021-06-07 17:12:22

線程安全Atomic

2024-03-28 10:37:44

IoC依賴注入依賴查找

2024-03-01 11:33:31

2024-12-04 14:45:14

零拷貝技術(shù)CPU 拷貝Zero-copy
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 五月婷婷丁香婷婷 | 欧美一区二区视频 | 亚洲电影一区 | 天天操天天干天天曰 | 久久激情视频 | 91精品国产欧美一区二区成人 | 国产96色在线 | 国产欧美精品一区二区色综合朱莉 | 久久精品一区二区三区四区 | 国产偷久久一级精品60部 | 狠狠的操 | 久久精品中文字幕 | 国精产品一区一区三区免费完 | 在线播放一区二区三区 | 久久男人| 亚洲精品久久久久久久久久久久久 | 久久久蜜臀国产一区二区 | 欧美日韩高清在线一区 | 日韩午夜| 日日日日日日bbbbb视频 | 亚洲精品国产精品国自产在线 | 亚洲一视频 | 国产精品国产a级 | h视频在线免费 | 久久精品欧美一区二区三区麻豆 | 亚洲 日本 欧美 中文幕 | 亚洲国产自产 | 超碰操 | 国产精品久久久久久久粉嫩 | 免费网站国产 | 欧美一级欧美一级在线播放 | 欧美日韩在线视频观看 | 欧美久久综合 | 国产精品久久久久久久久久三级 | 亚洲综合色视频在线观看 | 香蕉视频一区二区 | 国产成人高清在线观看 | 国产又爽又黄的视频 | 国产精品久久久 | 男女午夜免费视频 | 日韩一区二区三区在线视频 |