前言:本文章参考美团的线程池动态参数配置。测试有效 解析: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。