SpringBoot异步任务调用

SpringBoot中使用@EnableAsync@Async注解来实现异步任务功能,具体有如下三种方式,可自定义的程度依次递增。

方式一

Application启动类上加上@EnableAsync注解

package com.example.demo_asynctask;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@SpringBootApplication
public class DemoAsynctaskApplication {
    public static void main(String[] args) throws InterruptedException {
        SpringApplication.run(DemoAsynctaskApplication.class, args);
    }
}

异步方法上加上@Async注解(注意异步方法的调用方不可以和异步方法在同一个类中)

package com.example.demo_asynctask;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class AsyncTask {
    @Async
    public void task1() throws InterruptedException {
        Long beginTime = System.currentTimeMillis();
        Thread.sleep(1000L);
        Long endTime = System.currentTimeMillis();
        System.out.println("异步任务一,耗时:" + (endTime - beginTime) + "ms.");
    }
}

调用方示例

package com.example.demo_asynctask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
    @Autowired
    AsyncTask asyncTask;
    @GetMapping("/test")
    public void test() throws InterruptedException {
        Long beginTime = System.currentTimeMillis();
        asyncTask.task1();
        Long endTime = System.currentTimeMillis();
        System.out.println("调用函数,执行耗时:" + (endTime - beginTime) + "ms.");
    }
}

访问http://localhost:8080/test,控制台输出如下,证明调用方执行完毕时,异步任务仍在执行。

方式二

直接在Application启动类上加@EnableAsync注解不优雅,并且我们可能想自定义线程池的一些属性,因此去掉启动类上的注解,添加如下配置类

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }
}

异步任务类和调用类保持原样,即

@Component
public class AsyncTask {
    @Async
    public void task1() throws InterruptedException {
        Long beginTime = System.currentTimeMillis();
        Thread.sleep(1000L);
        Long endTime = System.currentTimeMillis();
        System.out.println("异步任务一,耗时:" + (endTime - beginTime) + "ms.");
    }
}
@RestController
public class TestController {
    @Autowired
    AsyncTask asyncTask;
    @GetMapping("/test")
    public void test() throws InterruptedException {
        Long beginTime = System.currentTimeMillis();
        asyncTask.task1();
        Long endTime = System.currentTimeMillis();
        System.out.println("调用函数,执行耗时:" + (endTime - beginTime) + "ms.");
    }
}

继续访问http://localhost:8080/test,控制台输出如下,

方式三

有时候我们想在不同的场景中使用不同的线程池来执行异步任务,有些需要更多的核心线程,有些需要更多的队列容量,为此需要创建多个配置类,例如

@Configuration
@EnableAsync
public class AsyncCustomConfig {
    @Bean("myAsyncExecutor")
    public Executor myAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(5);
        executor.initialize();
        return executor;
    }
}

然后再异步任务的@Aync上指定线程池,即

@Component
public class AsyncTask {
    @Async("myAsyncExecutor")
    public void task1() throws InterruptedException {
        Long beginTime = System.currentTimeMillis();
        Thread.sleep(1000L);
        Long endTime = System.currentTimeMillis();
        System.out.println("异步任务一,耗时:" + (endTime - beginTime) + "ms.");
    }
}

调用类保持不变

@RestController
public class TestController {
    @Autowired
    AsyncTask asyncTask;
    @GetMapping("/test")
    public void test() throws InterruptedException {
        Long beginTime = System.currentTimeMillis();
        asyncTask.task1();
        Long endTime = System.currentTimeMillis();
        System.out.println("调用函数,执行耗时:" + (endTime - beginTime) + "ms.");
    }
}

继续访问http://localhost:8080/test,控制台输出如下,

你可能感兴趣的:(SpringBoot异步任务调用)