吉林省白山市建设局官方网站,营销策划推广,搜索网站不显示图片,杭州做产地证去哪个网站线程池是Java多线程编程中的核心组件#xff0c;用于管理线程的生命周期、复用线程资源#xff0c;避免频繁创建和销毁线程带来的性能开销。在高并发场景#xff08;如Web服务器、微服务调用等#xff09;中#xff0c;合理使用线程池能显著提升系统性能和稳定性。 1. 为什…
线程池是Java多线程编程中的核心组件用于管理线程的生命周期、复用线程资源避免频繁创建和销毁线程带来的性能开销。在高并发场景如Web服务器、微服务调用等中合理使用线程池能显著提升系统性能和稳定性。 1. 为什么需要线程池 问题直接创建线程new Thread()的缺点 线程创建和销毁开销大涉及操作系统资源分配。 无限制创建线程会导致资源耗尽如内存溢出。 解决方案线程池通过复用线程、限制并发数、任务队列机制解决这些问题。 2. Java中的线程池实现
Java通过java.util.concurrent.ExecutorService接口及其实现类提供线程池支持核心实现类是ThreadPoolExecutor。
2.1 线程池的创建ThreadPoolExecutor
ThreadPoolExecutor executor new ThreadPoolExecutor(int corePoolSize, // 核心线程数长期存活的线程int maximumPoolSize, // 最大线程数临时线程 maximumPoolSize - corePoolSizelong keepAliveTime, // 临时线程空闲存活时间TimeUnit unit, // 时间单位秒/毫秒等BlockingQueueRunnable workQueue, // 任务队列RejectedExecutionHandler handler // 拒绝策略
);
关键参数说明
参数作用corePoolSize核心线程数即使空闲也不会被销毁除非allowCoreThreadTimeOuttrue。maximumPoolSize线程池最大能容纳的线程数核心线程 临时线程。keepAliveTime临时线程空闲时的存活时间超时后销毁。workQueue任务队列用于存放待执行的任务常见队列类型见下文。handler当线程池和队列都满时如何处理新任务拒绝策略。 2.2 任务队列BlockingQueue类型
队列类型特性ArrayBlockingQueue有界队列固定大小任务超出队列大小时会创建临时线程。LinkedBlockingQueue无界队列默认Integer.MAX_VALUE可能导致OOM。SynchronousQueue不存储任务直接交给线程执行需搭配maximumPoolSize使用。PriorityBlockingQueue带优先级的无界队列任务需实现Comparable。 2.3 拒绝策略RejectedExecutionHandler
当线程池和队列都满时对新任务的处理方式
策略名行为AbortPolicy默认直接抛出RejectedExecutionException。CallerRunsPolicy让提交任务的线程自己执行该任务同步执行。DiscardPolicy静默丢弃任务不抛异常。DiscardOldestPolicy丢弃队列中最旧的任务然后重新尝试提交当前任务。 3. 线程池的工作流程 提交任务调用executor.execute(Runnable task)或submit(Callable task)。 线程分配 如果当前线程数 corePoolSize立即创建新线程执行任务。 如果线程数 ≥ corePoolSize任务进入workQueue等待。 如果队列已满且线程数 maximumPoolSize创建临时线程执行任务。 如果队列和线程池均满触发拒绝策略。 线程回收 核心线程默认长期存活。 临时线程在空闲keepAliveTime后被销毁。 4. 常见的线程池工具类Executors
Java提供了Executors工具类快速创建线程池但需注意潜在问题
方法名底层实现问题newFixedThreadPool(int n)固定大小的线程池核心最大线程数无界队列无界队列可能导致OOM。newCachedThreadPool()可扩容线程池核心0最大Integer.MAX_VALUE线程数无限制可能创建过多线程导致资源耗尽。newSingleThreadExecutor()单线程池核心最大1无界队列无界队列可能导致OOM。newScheduledThreadPool()支持定时/周期性任务的线程池。无界队列可能导致OOM。 建议生产环境推荐手动创建ThreadPoolExecutor避免使用Executors的无界队列。 5. 线程池的最佳实践 合理配置参数 CPU密集型任务corePoolSize CPU核心数 1。 IO密集型任务corePoolSize 2 * CPU核心数。 避免无界队列使用ArrayBlockingQueue或自定义有界队列。 明确拒绝策略根据业务选择AbortPolicy日志记录 告警或CallerRunsPolicy。 监控线程池通过ThreadPoolExecutor的方法如getActiveCount()或Spring Boot Actuator。 6. 示例代码 // 手动创建线程池
ThreadPoolExecutor executor new ThreadPoolExecutor(2, // corePoolSize5, // maximumPoolSize60, TimeUnit.SECONDS, // keepAliveTimenew ArrayBlockingQueue(10), // 有界队列容量10new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);// 提交任务
executor.execute(() - {System.out.println(Task executed by Thread.currentThread().getName());
});// 关闭线程池平滑关闭
executor.shutdown(); 7. 常见面试题 线程池的底层原理是什么 corePoolSize和maximumPoolSize如何协作 无界队列会导致什么问题 如何优化线程池参数 线程池的拒绝策略有哪些如何选择 掌握线程池是Java高并发编程的基础也是面试高频考点。建议结合源码如ThreadPoolExecutor和实际场景如Web服务器请求处理加深理解。