一、背景描述

java 的代码是同步顺序执行,当我们需要执行异步操作时我们通常会去创建一个新线程去执行。比如new Thread()。start(),或者使用线程池线程池 new ThreadPoolExecutor().execute 。

在 Springboot 中对其进行了简化处理,使用@EnableAsync + @Async 可以快速开启一个异步线程执行任务

二、简单使用方法

启动类上使用 @EnableAsync ,开启异步任务支持

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

在需要异步执行的方法上添加注解 @Async

   @GetMapping("hello")
    public String hello(){
        asyncService.hello();
        System.out.println(new Date() + "success");
        return "ok";
    }

  @Async
    public void hello() {

        System.out.println(new Date() + "  " + Thread.currentThread().getName() + Thread.currentThread().getId());
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(new Date() + "  " + Thread.currentThread().getName() + Thread.currentThread().getId() + "---->处理end");
    }

测试 Jemeter同时发送两个请求
SpringBoot整合、SpringBoot与异步任务-LMLPHP

三、原理

【看不太懂,之后再进行整理吧】

五、使用自定义线程池

@Async默认使用的是 SimpleAsyncTaskExecutor , execute时,直接new Tread来执行该任务
SpringBoot整合、SpringBoot与异步任务-LMLPHP

六、@Async失效情况

同一个类中,一个方法调用 @Async标注的方法

@Service
public class AsyncDemoImpl implements AsyncDemo {

    // 注入spring上下文
    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void a() {
        System.out.println("开始执行a(): " + TimeUtil.getStringDate());

        // 通过上下文获取该类的实例,再调用该实例方法
        AsyncDemo asyncDemo = applicationContext.getBean(AsyncDemo.class);

        asyncDemo.b();

        System.out.println("执行结束a(): " + TimeUtil.getStringDate());

    }

    @Async
    @Override
    public void b() {
        System.out.println("开始执行b(): " + TimeUtil.getStringDate());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行结束b(): " + TimeUtil.getStringDate());
    }
}
08-12 08:20