# dynamicthreadpoll **Repository Path**: licdjdli/dynamicthreadpoll ## Basic Information - **Project Name**: dynamicthreadpoll - **Description**: 根据工作心得,结合spring源码拓展,手写一个高性能,可拓展的动态线程池,主要解决传统静态线程池中的资源耗尽风险,无法自定义配置,不适用于异步编程,线程池监控困难......等问题。动态线程池的设计主要有“动态加载Bean”,“动态读取配置”,“spring事件机制推送”,“告警压测”,“开箱即用”等设计思想和方法。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-21 - **Last Updated**: 2025-11-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dynamicthreadpoll #### 一.介绍 根据工作心得,结合spring源码拓展,手写一个高性能,可拓展的动态线程池,主要解决传统静态线程池中的资源耗尽风险,无法自定义配置,不适用于异步编程,线程池监控困难......等问题。动态线程池的设计主要有“动态加载Bean”,“动态读取配置”,“spring事件机制推送”,“告警压测”,“开箱即用”等设计思想和方法。 当然本案例并非全部代码,只是部分核心思路体现设计体现。 #### 二.传统的线程池有什么缺点 ##### 1.资源耗尽风险 固定大小的线程池(newFixedThreadPool)和单线程线程池(newSingleThreadExecutor)使用无界的工作队列(LinkedBlockingQueue),当任务提交速度超过处理速度时,会导致大量任务堆积在队列中,占用大量内存,甚至导致OOM。 ##### 2.无法自定义配置 Executors提供的静态方法创建的线程池,其参数(如核心线程数、最大线程数、队列类型等)是固定的,无法根据实际需求灵活调整。 ##### 3.不适用于异步编程 传统的线程池提交任务后,获取结果需要通过Future的get方法,这是阻塞的,对于异步编程来说不够友好。 ##### 4.任务执行异常处理 默认情况下,如果任务执行过程中抛出异常,线程池会打印异常堆栈并终止当前线程,然后创建新的线程来替代。但这种方式可能无法满足自定义异常处理的需求。 ##### 5.线程池监控困难 传统的线程池缺乏有效的监控手段,比如任务执行数量、队列大小、活跃线程数等指标的获取并不方便。 ##### 6.资源浪费 缓存线程池(newCachedThreadPool)可以无限创建线程,可能导致线程数量过多,消耗大量系统资源。 ##### 7.不支持动态调整 线程池创建后,其核心参数(如核心线程数、最大线程数)不能动态修改,无法适应负载变化。 #### 三.解决方案 ##### 1.使用有界队列 避免使用无界队列,可以使用ArrayBlockingQueue或有界LinkedBlockingQueue,并合理设置队列大小,防止内存溢出。 ##### 2.自定义线程池 直接使用ThreadPoolExecutor构造函数创建线程池,根据业务需求灵活配置核心线程数、最大线程数、队列类型和大小、拒绝策略等。 ##### 3.使用CompletableFuture进行异步编程 Java 8引入了CompletableFuture,它提供了更强大的异步编程能力,可以结合线程池使用,实现非阻塞的任务处理。 ##### 4.自定义拒绝策略 当队列满且线程数达到最大时,可以自定义拒绝策略(RejectedExecutionHandler),比如记录日志、暂存任务等。 ##### 5.增加监控 可以通过扩展ThreadPoolExecutor,重写beforeExecute、afterExecute和terminated方法,来监控任务执行情况。也可以使用Spring的ThreadPoolTaskExecutor,它提供了更多的监控指标。 ##### 6.使用动态线程池 可以考虑使用支持动态调整参数的线程池,例如Hippo4j、DynamicTp等开源项目,它们允许在运行时调整线程池参数。 ##### 7.合理配置线程池参数 根据业务类型(CPU密集型、IO密集型)和系统资源,合理设置线程池大小。通常,CPU密集型任务可以设置线程数为CPU核数+1,IO密集型任务可以设置更多线程,因为IO操作不会占用CPU。 ##### 8.使用合适的拒绝策略 根据业务重要性,选择不同的拒绝策略,如丢弃最老任务、丢弃当前任务、调用者运行等 #### 四.怎么实现 ##### 4.1 线程池参数以及个数来自与配置文件 ##### 4.2 动态的注册线程池的Bean ##### 4.3 动态读取配置文件 ##### 4.4 管理注册的Bean ##### 4.5 监控线程池