@Async与异步任务——阅读开源项目中的代码

@Async注解:将一个方法指定为异步执行任务。需要配合线程池使用

示例:
  1、建立Bean实体,使用@Async配置异步任务
 1 import org.springframework.scheduling.annotation.Async;
 2 import org.springframework.stereotype.Service;
 3 
 4 /**
 5  * Created by sang on 16-12-14.
 6  */
 7 @Service
 8 public class AsyncTaskService {
 9     @Async
10     public void executeAsyncTask(int i) {
11         System.out.println("异步任务1:" + i+";Thread.currentThread().getName():"+Thread.currentThread().getName());
12     }
13 
14     @Async
15     public void executeAsyncTask2(int i) {
16         System.out.println("异步任务2:" + i+";Thread.currentThread().getName():"+Thread.currentThread().getName());
17     }
18 }

 

  2、配置异步执行环境:需要实现AsyncConfigurer接口

 1 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
 2 import org.springframework.context.annotation.ComponentScan;
 3 import org.springframework.context.annotation.Configuration;
 4 import org.springframework.scheduling.annotation.AsyncConfigurer;
 5 import org.springframework.scheduling.annotation.EnableAsync;
 6 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 7 
 8 import java.util.concurrent.Executor;
 9 
10 @Configuration
11 @ComponentScan("com.yrc.taskexecutor")
12 @EnableAsync    //开启异步任务支持
13 public class TaskExecuteConfig implements AsyncConfigurer {
14   //获得基于线程池的任务执行器
15     @Override
16     public Executor getAsyncExecutor() {
17         //创建线程执行器
18         ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
19         //执行核心线程数
20         taskExecutor.setCorePoolSize(2);
21         //指定线程最大数量
22         taskExecutor.setMaxPoolSize(5);
23         //指定任务队列最大长度
24         taskExecutor.setQueueCapacity(25);
25         //初始化执行器
26         taskExecutor.initialize();
27         return taskExecutor;
28     }
29 
30     @Override
31     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
32         return null;
33     }
34 }

 

  3、模拟调用:

 

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String args[]){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecuteConfig.class);
        AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class);
        for(int i=0;i<10;i++){
            asyncTaskService.executeAsyncTask1(i);
            asyncTaskService.ExecuteAsyncTask2(i);
        }
        context.close();

    }
}

 

异步任务调用大致流程:当外部执行异步任务调用时,任务的实际执行会委派给线程池中的工作线程。先查询线程池中是否存在空闲线程,如果有,则立即将任务交给该工作线程,如果没有,则检测当前线程数量是否达到最大线程数量,没有则创建线程并交付任务,如果已经达到了最大线程数量,则检测当前任务队列是否满,如果没有满,则将任务放置入任务队列,如果 任务队列也满了,则执行相应的任务放弃策略。当主线程将工作交给任务线程后,就可以去执行其他任务,而工作线程在执行完任务后会将结果存入Future,然后根据当前状态和自己的身份选择继续存在还是销毁。当主线程想要获得最终结果时,调用Future.

posted @ 2020-05-22 16:29  怪兽不纯粹  阅读(206)  评论(0)    收藏  举报