当前位置 熊猫博客 JAVA 正文 下一篇:

Spring Boot异步任务

使用Spring Boot实现异步执行任务很简单,这里讲两个方面,一个是无返回值的异步任务,一个是有返回值的异步任务,后者稍稍有些复杂。

打开异步配置

首先要做的是打开spring boot的异步配置,在SpringBootApplication类中使用注解@EnableAsync

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class PlatformApplication {

    public static void main(String[] args) {
        SpringApplication.run(PlatformApplication.class, args);
    }

}

配置异步任务

在被异步执行的方法签名上增加@Async注解即可,如果不配置线程池,那么使用的是默认的SimpleAsyncTaskExecutor线程池,它并不是真正意义上的线程池,每次调用都会创建一个新的线程,具有很大的风险。

创建自定义线程池

使用spring提供的ThreadPoolTaskExecutor实现

@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Bean("testAsync")
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 配置核心线程数
        taskExecutor.setCorePoolSize(20);
        // 配置最大线程数
        taskExecutor.setMaxPoolSize(30);
        // 配置队列数
        taskExecutor.setQueueCapacity(2000);
        // 配置线程前缀
        taskExecutor.setThreadNamePrefix("myAsyncTask-");
        // 拒绝策略
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }
}

以上代码中指定了线程池名称为testAsync,并配置了线程池数量、队列、前缀和拒绝策略。

在@Async注解中指定要使用的线程池即可。

@Service
public class AsyncServiceImpl implements AsyncService {
    @Override
    @Async("testAsync")
    public void makeReport() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    }
}

自调用失效的问题原因

使用spring boot异步任务时,不要使用自身调用,否则是不生效的,像这样

@Service
public class AsyncServiceImpl implements AsyncService {
    @Override
    @Async("testAsync")
    public void makeReport() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        System.out.println("begin");
        for (int i = 0; i < 3; i++) {
            AsyncServiceImpl asyncService = new AsyncServiceImpl();
            asyncService.makeReport();
        }
        System.out.println("end");
    }
}

运行结果如下:

要使用spring boot的异步任务,调用必须交给sping容器处理,这是由spring的调用机制造成的。

带返回值的异步任务

待补充

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

4条评论

    1. 这个分类下的文章都是记录编程的,是我平时的所学所想,跟wp无关。wp有关的东西我基本上不会再搞了,没有时间。^_^

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部