@Async实现异步调用:ThreadPoolTaskScheduler线程池的优雅关闭

该文章介绍了如何在SpringBoot中使用@Async注解实现异步调用,并配置ThreadPoolTaskScheduler进行线程池的初始化。同时,文章讨论了如何实现线程池的优雅关闭,包括设置等待任务完成和设置拒绝策略。此外,还提供了一个自定义的AsyncUncaughtExceptionHandler来处理异步任务中的异常。在服务停止时,通过监听ContextClosedEvent事件来销毁线程池。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Boot使用@Async实现异步调用:ThreadPoolTaskScheduler线程池的优雅关闭_weixin_34413065的博客-CSDN博客

由@Async使用引发的思考,实现优雅关闭线程_weixin_34224941的博客-CSDN博客

https://download.csdn.net/download/weixin_38642897/12760463

写这篇文章不为别的,就因为上面三篇文章的要收费、要会员??开源的东西大伙分享

线程池初始化

import com.petrochina.gsms.foundation.json.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定义异步任务线程池, 异步任务异常捕获处理器
 */
@Slf4j
@EnableAsync    // 开启 Spring 异步任务支持
@Configuration
public class AsyncPoolConfig implements AsyncConfigurer {
	
    /***
     * 初始化线程池
     * @time 创建时间 2023/6/22 16:24
     * @author hgg
     **/
    @Bean
    public Executor getDrsSyncExecutor() {
        final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(500);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("xxx-thread-");
        // 等待所有任务结果候再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        // 定义拒绝策略
        executor.setRejectedExecutionHandler(
                new ThreadPoolExecutor.AbortPolicy()
        );
        // 初始化线程池, 初始化 core 线程
        executor.initialize();
        log.info("drs增量消费线程池-初始化完成……");
        return executor;
    }

    /**
     * 指定系统中的异步任务在出现异常时使用到的处理器
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }

    /**
     * 异步任务异常捕获处理器
     */
    @SuppressWarnings("all")
    class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
        @Override
        public void handleUncaughtException(Throwable throwable, Method method,
                                            Object... objects) {
            throwable.printStackTrace();
            log.error("Async Error: [{}], Method: [{}], Param: [{}]",
                    throwable.getMessage(), method.getName(),
                    JsonUtil.toJson(objects));
        }
    }
}

监听服务停止:

Spring环境中正确关闭线程池的姿势

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 监听AppContext关闭事件,销毁线程池
 */
@Component
@Slf4j
public class AppContextClosedHandler implements ApplicationListener<ContextClosedEvent> {
    /**
     * 初始化的线程池bean
     */
    @Resource(name = "getDrsSyncExecutor")
    private ThreadPoolTaskExecutor executor;

    @Override
    public void onApplicationEvent(final ContextClosedEvent event) {
        log.info("destroy thread executor start...增量队列任务:{},进行中任务:{}", executor.getQueueSize(), executor.getActiveCount());
        executor.destroy();
        log.info("destroy thread executor end!!!");
    }
}

效果图:

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多来哈米

还可以打赏???来试一毛

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值