java线程池参数动态化方案

    技术2022-07-12  66

    前言:本文章参考美团的线程池动态参数配置。测试有效 解析:jdk提供了一套下线程池参数动态化的api

    分为两部分

    1.阻塞队列的修改

    2.其他参数的修改

    第一部分 public class ThreadPoolChangeDemo {     public static void main(String[] args) throws InterruptedException {         dynamicThreadPool();     }     public static ThreadPoolExecutor buildThreadPool(){         return new ThreadPoolExecutor(2,                 50,                 60,                 TimeUnit.SECONDS,                 new LinkedBlockingQueue<>(50),                 new ThreadFactory() {                     @Override                     public Thread newThread(Runnable r) {                         return new Thread();                     }                 });     }     private static void dynamicThreadPool() throws InterruptedException {         ThreadPoolExecutor threadPoolExecutor = buildThreadPool();         for (int i = 0; i < 15; i++) {             threadPoolExecutor.submit(()->{                 printPoolSize(threadPoolExecutor,"创建线程池!!!!");                 try {                     TimeUnit.SECONDS.sleep(5000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             });         }         printPoolSize(threadPoolExecutor,"改变之前");         TimeUnit.SECONDS.sleep(1);         threadPoolExecutor.setMaximumPoolSize(100);         threadPoolExecutor.setCorePoolSize(50);         threadPoolExecutor.prestartAllCoreThreads(); //        Resize linkedBlockingQueue = (LinkedBlockingQueue) threadPoolExecutor.getQueue();         printPoolSize(threadPoolExecutor,"改变之后");     }     private static void printPoolSize(ThreadPoolExecutor pool,String name){         LinkedBlockingQueue linkedBlockingQueue = (LinkedBlockingQueue) pool.getQueue();         System.out.println(name);          System.out.println("最大线程数:"+pool.getMaximumPoolSize());         System.out.println("核心线程数:"+pool.getCorePoolSize());         System.out.println("线程池活跃度:"+(pool.getActiveCount()/pool.getMaximumPoolSize()));         System.out.println("队列大小:"+linkedBlockingQueue.size());         System.out.println("队列剩余大小:"+linkedBlockingQueue.remainingCapacity());     } }

    第二部分

    思路: LinkedBlockingQueue 粘贴一份出来,修改个自定义的队列名字,然后把 Capacity 参数的 final 修饰符去掉,并提供其对应的 get/set 方法。

    然后在程序里面把原来的队列换掉:

    运行起来看看效果:

    可以看到,队列大小确实从 10 变成了 100,队列使用度从 100% 降到了 9%

    这个过程中涉及到的面试题有哪些?

    问题一:线程池被创建后里面有线程吗?如果没有的话,你知道有什么方法对线程池进行预热吗?

    线程池被创建后如果没有任务过来,里面是不会有线程的。如果需要预热的话可以调用下面的两个方法:

    全部启动:

    仅启动一个:

    问题二:核心线程数会被回收吗?需要什么设置?

    核心线程数默认是不会被回收的,如果需要回收核心线程数,需要调用下面的方法:

    allowCoreThreadTimeOut 该值默认为 false。

    Processed: 0.011, SQL: 9