美文网首页
SpringBoot异步任务

SpringBoot异步任务

作者: 凯凯frank | 来源:发表于2020-02-18 22:47 被阅读0次

1. pom文件里依赖这个包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

2.应用启动类添加@EnableAsync注解

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

3.配置异步任务线程池

由于默认的异步任务会开启始终会一个新的线程,不利于资源的重复利用,所以,要编写一个异步任务的线程池

//AsyncPoolConfig.java
@Configuration
public class AsyncPoolConfig implements AsyncConfigurer {
    private final Logger logger = LoggerFactory.getLogger(MyAsyncTask.class);

    @Bean
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);// 设置核心线程池线程的数量,默认是1
        executor.setMaxPoolSize(20); // 线程池最大的线程数量,当核心线程都被用光,且缓冲队列是满的之后才申请
        executor.setQueueCapacity(20); // 缓冲队列中任务的个数
        executor.setKeepAliveSeconds(60); // 超出核心线程数的其他线程在空闲时的最大的存活时间
        executor.setThreadNamePrefix("frank_"); //线程池中的线程名称前缀

        executor.setWaitForTasksToCompleteOnShutdown(true);//程序关闭后,是否等待异步任务完成, 等待的时间需要配置, 默认false,
        executor.setAwaitTerminationSeconds(60);// 等待的时间,默认0

        //拒绝策略 线程池中的最大线程线程数用光,且缓冲队列也满了,可以选择的策略
        // DiscardPolicy: 丢弃需要添加的新的任务
        // AbortPolicy: 直接抛出异常
        // DiscardOldestPolicy: 丢弃阻塞队列的队头任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return executor;
    }

    //异步任务异常处理类,只会处理没有返回值的异步任务的异常
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }

    class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler{
        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
            logger.info("AsyncException:{}, Method:{}, Params:{}", throwable, method, objects);

            throwable.printStackTrace();
            //TODO 发送邮件或者短信
        }
    }
}

4.编写异步任务

@Component
public class MyAsyncTask {
    private final Logger logger = LoggerFactory.getLogger(MyAsyncTask.class);

    @Async("getAsyncExecutor")
    public void asyncProcess() throws InterruptedException {
        logger.info("async process task, current thread name -> {}", Thread.currentThread().getName());
        Thread.sleep(10000);
        //int a = 1/0;
    }

    @Async("getAsyncExecutor")
    public Future<Integer> asyncProcessHasReturn() throws InterruptedException {
        logger.info("async process task(has return), current thread name -> {}", Thread.currentThread().getName());
        Thread.sleep(10000);
        //int a = 1/0;
        return new AsyncResult<>(100);
    }
}

5.使用

@Autowired
private MyAsyncTask myAsyncTask;

logger.info("current thread name:", Thread.currentThread().getName());
myAsyncTask.asyncProcess();
Future<Integer> result = myAsyncTask.asyncProcessHasReturn();
logger.info("reuslt:{}", result.get(1, TimeUnit.SECONDS));//1s后定时任务没执行完就抛异常

相关文章

网友评论

      本文标题:SpringBoot异步任务

      本文链接:https://www.haomeiwen.com/subject/wovnfhtx.html