1. 配置类创建线程池全局单例只创建一次importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.concurrent.*;/** * 线程池配置 * 全局单例程序启动时创建一次一直用到停机 */ConfigurationpublicclassThreadPoolConfig{/** * 核心线程数根据 CPU 核心数调整 * IO密集型如查询、接口调用CPU核心数 * 2 * CPU密集型计算、加密CPU核心数 1 */privatestaticfinalintCORE_POOL_SIZE10;/** * 最大线程数 */privatestaticfinalintMAX_POOL_SIZE20;/** * 空闲线程存活时间 */privatestaticfinallongKEEP_ALIVE_SECONDS60L;/** * 队列容量根据业务压测调整 */privatestaticfinalintQUEUE_CAPACITY1000;BeanpublicThreadPoolExecutorbusinessThreadPool(){returnnewThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE,KEEP_ALIVE_SECONDS,TimeUnit.SECONDS,newLinkedBlockingQueue(QUEUE_CAPACITY),// 自定义线程名生产必备方便排查问题newThreadFactory(){privatefinalintindex0;OverridepublicThreadnewThread(Runnabler){returnnewThread(r,business-pool-index);}},// 拒绝策略队列满了就抛异常防止压垮服务newThreadPoolExecutor.AbortPolicy());}}2. 业务类使用线程池永不关闭importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.concurrent.ThreadPoolExecutor;ServicepublicclassBusinessService{// 注入全局唯一的线程池AutowiredprivateThreadPoolExecutorbusinessThreadPool;/** * 业务方法异步执行任务 * 运行期间可以无限次调用线程复用不关闭 */publicvoiddoAsyncTask(){businessThreadPool.execute(()-{try{// 执行业务逻辑异步发送消息、记录日志、处理数据...System.out.println(线程Thread.currentThread().getName() 执行异步任务);}catch(Exceptione){e.printStackTrace();}});}}3. 停机类优雅关闭线程池只在停机时调用一次importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importjavax.annotation.PreDestroy;importjava.util.concurrent.ThreadPoolExecutor;importjava.util.concurrent.TimeUnit;/** * 应用停机时优雅关闭线程池 * 确保任务执行完不丢数据不暴力停机 */ComponentpublicclassThreadPoolShutdownManager{AutowiredprivateThreadPoolExecutorbusinessThreadPool;/** * Spring 容器销毁前执行停机钩子 */PreDestroypublicvoidshutdownThreadPool(){System.out.println(应用停机开始优雅关闭线程池...);// 第一步拒绝新任务执行完队列中已有的任务businessThreadPool.shutdown();try{// 等待 3 秒让任务执行完if(!businessThreadPool.awaitTermination(3,TimeUnit.SECONDS)){// 超时还没关闭 → 强制关闭中断正在执行的任务System.out.println(线程池关闭超时强制关闭);businessThreadPool.shutdownNow();}}catch(InterruptedExceptione){// 被中断 → 强制关闭businessThreadPool.shutdownNow();Thread.currentThread().interrupt();}System.out.println(线程池已安全关闭);}}这个流程的核心规则你刚才所有疑问的答案创建应用启动时创建一次全局单例使用运行期间无限次提交任务从不主动关闭关闭只有应用停机时通过PreDestroy自动执行一次关闭关闭目的不是销毁线程池而是等待任务执行完毕安全停机一句话总结最佳实践启动创建一次运行一直复用停机优雅关闭。
Java线程池创建、使用和关闭
发布时间:2026/6/4 3:26:49
1. 配置类创建线程池全局单例只创建一次importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.concurrent.*;/** * 线程池配置 * 全局单例程序启动时创建一次一直用到停机 */ConfigurationpublicclassThreadPoolConfig{/** * 核心线程数根据 CPU 核心数调整 * IO密集型如查询、接口调用CPU核心数 * 2 * CPU密集型计算、加密CPU核心数 1 */privatestaticfinalintCORE_POOL_SIZE10;/** * 最大线程数 */privatestaticfinalintMAX_POOL_SIZE20;/** * 空闲线程存活时间 */privatestaticfinallongKEEP_ALIVE_SECONDS60L;/** * 队列容量根据业务压测调整 */privatestaticfinalintQUEUE_CAPACITY1000;BeanpublicThreadPoolExecutorbusinessThreadPool(){returnnewThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE,KEEP_ALIVE_SECONDS,TimeUnit.SECONDS,newLinkedBlockingQueue(QUEUE_CAPACITY),// 自定义线程名生产必备方便排查问题newThreadFactory(){privatefinalintindex0;OverridepublicThreadnewThread(Runnabler){returnnewThread(r,business-pool-index);}},// 拒绝策略队列满了就抛异常防止压垮服务newThreadPoolExecutor.AbortPolicy());}}2. 业务类使用线程池永不关闭importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.concurrent.ThreadPoolExecutor;ServicepublicclassBusinessService{// 注入全局唯一的线程池AutowiredprivateThreadPoolExecutorbusinessThreadPool;/** * 业务方法异步执行任务 * 运行期间可以无限次调用线程复用不关闭 */publicvoiddoAsyncTask(){businessThreadPool.execute(()-{try{// 执行业务逻辑异步发送消息、记录日志、处理数据...System.out.println(线程Thread.currentThread().getName() 执行异步任务);}catch(Exceptione){e.printStackTrace();}});}}3. 停机类优雅关闭线程池只在停机时调用一次importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importjavax.annotation.PreDestroy;importjava.util.concurrent.ThreadPoolExecutor;importjava.util.concurrent.TimeUnit;/** * 应用停机时优雅关闭线程池 * 确保任务执行完不丢数据不暴力停机 */ComponentpublicclassThreadPoolShutdownManager{AutowiredprivateThreadPoolExecutorbusinessThreadPool;/** * Spring 容器销毁前执行停机钩子 */PreDestroypublicvoidshutdownThreadPool(){System.out.println(应用停机开始优雅关闭线程池...);// 第一步拒绝新任务执行完队列中已有的任务businessThreadPool.shutdown();try{// 等待 3 秒让任务执行完if(!businessThreadPool.awaitTermination(3,TimeUnit.SECONDS)){// 超时还没关闭 → 强制关闭中断正在执行的任务System.out.println(线程池关闭超时强制关闭);businessThreadPool.shutdownNow();}}catch(InterruptedExceptione){// 被中断 → 强制关闭businessThreadPool.shutdownNow();Thread.currentThread().interrupt();}System.out.println(线程池已安全关闭);}}这个流程的核心规则你刚才所有疑问的答案创建应用启动时创建一次全局单例使用运行期间无限次提交任务从不主动关闭关闭只有应用停机时通过PreDestroy自动执行一次关闭关闭目的不是销毁线程池而是等待任务执行完毕安全停机一句话总结最佳实践启动创建一次运行一直复用停机优雅关闭。