springboot公共线程池配置

文章介绍了如何在SpringBoot应用中配置一个通用的线程池,包括核心线程数、最大线程数、队列容量和线程活跃时间。同时,还展示了如何通过UserTaskDecorator传递用户信息到线程中。
@Configuration
public class TzCommonThreadPoolConfig {

    /**
     * 线程池配置:核心线程数
     */
    @Value("${sys.pool.corePoolSize:8}")
    private int corePoolSize;

    /**
     * 线程池配置:最大线程数
     */
    @Value("${sys.pool.maxPoolSize:16}")
    private int maxPoolSize;

    /**
     * 线程池配置:队列容量
     */
    @Value("${sys.pool.commonQueueCapacity:2048}")
    private int queueCapacity;

    /**
     * 线程池配置:线程活跃时间(秒)
     */
    @Value("${sys.pool.commonKeepAliveSeconds:60}")
    private int keepAliveSeconds;

    /**
     * 通用公共线程池
     * <p>
     * 可传递当前用户信息
     * 非强业务性配置,默认使用通用配置量,队列容量和活跃时间自定义
     * 频率较高及业务性较强的建议自定义线程池处理
     *
     * @return Executor
     */
    @Bean(name = "commonThreadPool")
    public Executor commonThreadPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(corePoolSize);
        // 设置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 设置队列容量
        executor.setQueueCapacity(queueCapacity);
        // 设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置默认线程名称
        executor.setThreadNamePrefix("commonThreadPool-%d");
        // 增加 TaskDecorator 属性的配置
        executor.setTaskDecorator(new UserTaskDecorator());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 初始化线程池
        executor.initialize();
        return executor;
    }
}
/**
* 用户信息传递装饰器
*/
public class UserTaskDecorator implements TaskDecorator {

    /**
     * Decorate the given {@code Runnable}, returning a potentially wrapped
     * {@code Runnable} for actual execution, internally delegating to the
     * original {@link Runnable#run()} implementation.
     *
     * @param runnable the original {@code Runnable}
     * @return the decorated {@code Runnable}
     */
    @Override
    public Runnable decorate(@NotNull Runnable runnable) {
        TzmallUser user = UserInfoContext.getUser();
        return () -> UserInfoContext.resetUserInfo(user, runnable::run);
    }
}
public class UserInfoContext {

    /**
     * 用户信息ThreadLocal
     */
    private static ThreadLocal<TzmallUser> userInfo = new ThreadLocal<>();

    /**
     * 获取Authentication
     */
    public static Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }

    /**
     * 默认用户
     */
    private final static TzmallUser defaultUser;

    static {
        defaultUser = new TzmallUser(TzmallUser.SYSTEM, StrUtil.EMPTY, Collections.emptySet());
        defaultUser.setId(xxL);
        defaultUser.setName("系统");
        defaultUser.setFirmId(xxL);
        defaultUser.setFirmName("平台");
        defaultUser.setUserType(xx);
        defaultUser.setPhone("");
    }

    public UserInfoContext() {
    }

    /**
     * 获取用户信息
     */
    public static TzmallUser getUser(){
        // 如果本地缓存存在,则返回本地缓存TzUser
        if (ObjectUtil.isNotNull(userInfo.get())) {
            return userInfo.get();
        }
        Authentication authentication = getAuthentication();
        if (authentication == null) {
            return null;
        }
        return getUser(authentication);
    }


    /**
     * 获取用户信息
     *
     * @param authentication authentication
     * @return TzmallUser
     */
    public static TzmallUser getUser(Authentication authentication) {
        Object principal = authentication.getPrincipal();
        if (principal instanceof TzmallUser) {
            return (TzmallUser) principal;
        }
        return null;
    }

    /**
     * 获取登录用户(如果当前未登录抛出异常!)
     *
     * @return TzmallUser
     */
    public static TzmallUser getLoginUser() {
        TzmallUser tzUser = getUser();
        if (tzUser == null) {
            throw new ServiceException(CodeMsg.LOGIN_INVALID);
        }
        return tzUser;
    }


    /**
     * 获取用户信息,如不存在取默认用户对象
     *
     */
    public static TzmallUser getUserOrDefault(){
        TzmallUser user = getUser();
        if (user == null) {
            return defaultUser;
        }
        return user;
    }

    /**
     * 重置登录信息,并执行代码
     *
     */
    public static <T> T resetUserInfo(TzmallUser tzUser, Supplier<T> supplier) {
        TzmallUser originalUser = userInfo.get();
        try {
            userInfo.set(tzUser);
            return supplier.get();
        } finally {
            if (originalUser == null) {
                userInfo.remove();
            } else {
                userInfo.set(originalUser);
            }
        }
    }

    /**
     * 重置登录信息,并执行代码
     *
     */
    public static void resetUserInfo(TzmallUser tzUser, LambdaExecutor lambdaExecutor) {
        TzmallUser originalUser = userInfo.get();
        try {
            userInfo.set(tzUser);
            lambdaExecutor.executor();
        } finally {
            if (originalUser == null) {
                userInfo.remove();
            } else {
                userInfo.set(originalUser);
            }
        }
    }
}

配置类放在common,引用该common的模块相当于建立了自己的线程池

#启动类添加
@EnableAsync
#使用
@Async("commonThreadPool")
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值