在不停服务的基础上改变线程池的最大线程数

本文介绍了如何在Java中自定义线程池,并利用Apollo配置中心实现实时动态调整线程池的最大线程数,同时提及了扩展至核心线程数和空闲线程存活时间的可能方法。
摘要由CSDN通过智能技术生成

1 概述

在不停服务的基础上改变线程池的最大线程数,并使改变生效,关键点如下:

(1)通过线程池自带的方法设置线程池的最大线程数。

(2)通过配置中心触发线程池的最大线程数的改变。

2 具体实现

2.1 自定义线程池

@Slf4j
public class CommonThreadPoolUtil {

    private static final int CORE_SIZE = Runtime.getRuntime().availableProcessors() * 2;
    private static final int MAX_SIZE = CORE_SIZE + 10;
    private static final int WORK_QUEUE_CAPACITY = 10000;
    private static final long KEEP_ALIVE_TIME = 120;
    private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
    /**
     * 采用默认的队列策略,队列已满时拒绝任务
     */
    private final static ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(CORE_SIZE, MAX_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
            new LinkedBlockingDeque<>(WORK_QUEUE_CAPACITY));

    /**
     * 功能描述:提交一个异步任务交给线程池执行
     */
    public static void submitTask(String taskDesc, Runnable task) {
        log.info("异步任务[{}]提交到线程池....", taskDesc);
        try {
            EXECUTOR.execute(task);
        } catch (Exception e) {
            log.error("异步任务[{}]提交到线程池失败", taskDesc, e);
        }
    }

    /**
     * 获取线程池
     */
    public static ThreadPoolExecutor getExecutor() {
        return EXECUTOR;
    }

    /**
     * 设置线程池最大线程数
     */
    public static void setMaximumPoolSize(Integer maximumPoolSize) {
        if (maximumPoolSize < CORE_SIZE) {
            log.info("CommonThreadPoolUtil.setMaximumPoolSize 设置失败. 最大线程数小于核心线程数。maximumPoolSize:{},CORE_SIZE:{}", maximumPoolSize, CORE_SIZE);
            return;
        }

        int maximumPoolSizeOld = EXECUTOR.getMaximumPoolSize();
        try {
            EXECUTOR.setMaximumPoolSize(maximumPoolSize);
            log.info("CommonThreadPoolUtil.setMaximumPoolSize 设置成功. 线程池最大线程数由{}变为{}", maximumPoolSizeOld, EXECUTOR.getMaximumPoolSize());
        } catch (Exception e) {
            log.error("CommonThreadPoolUtil.setMaximumPoolSize 设置失败. maximumPoolSize:{}", maximumPoolSize, e);
        }
    }
}

2.2 动态改变线程池的最大线程数

借助于apollo配置中心,对Apollo配置进行动态监听。

@Slf4j
@Component
public class ApolloListener implements CommandLineRunner {
    @ApolloConfig("application.yml")
    private Config config;

    @Value("${commonThreadPoolUtil.maxPoolSize:0}")
    private Integer maxPoolSize4CommonThreadPoolUtil;

    @Override
    public void run(String... args) throws Exception {
        config.addChangeListener(changeEvent -> {
            log.info("Apollo config changed for namespace:{} ", changeEvent.getNamespace());
            changeEvent.changedKeys().forEach(key -> {
                String oldValue = changeEvent.getChange(key).getOldValue();
                String newValue = changeEvent.getChange(key).getNewValue();
                log.info("Apollo config changed, key:{}, old value: {}, new value: {}", key, oldValue, newValue);

                // 更新线程池最大线程数
                setMaximumPoolSize( key,  oldValue,  newValue);

            });
        });
    }

    private void setMaximumPoolSize(String key, String oldValue, String newValue) {
        if (Objects.equals(key, "commonThreadPoolUtil.maxPoolSize") && !Objects.equals(oldValue, newValue)) {
            if (Integer.parseInt(newValue) < CommonThreadPoolUtil.getExecutor().getCorePoolSize()) {
                log.warn("new value is less than core pool size, ignore");
                return;
            }
            CommonThreadPoolUtil.setMaximumPoolSize(Integer.parseInt(newValue));
            log.info("CommonThreadPoolUtil maximumPoolSize {}", CommonThreadPoolUtil.getExecutor().getMaximumPoolSize());
        }
    }
}

3 扩展

动态修改核心线程数空闲线程存活时间的实现方式也可以采用类似方式实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值