线程池概述
Java线程池是一种池化技术,用于管理和复用线程,减少线程创建和销毁的开销,提高系统性能。Java通过java.util.concurrent
包提供了强大的线程池支持。
线程池参数详解
1. 核心参数
// 创建线程池的完整构造函数
ThreadPoolExecutor(int corePoolSize, // 核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime, // 空闲线程存活时间TimeUnit unit, // 时间单位BlockingQueue<Runnable> workQueue, // 工作队列ThreadFactory threadFactory, // 线程工厂RejectedExecutionHandler handler // 拒绝策略处理器
)
2. 参数详细说明
corePoolSize(核心线程数)
-
线程池中保持的最小线程数量,即使它们是空闲的
-
除非设置了
allowCoreThreadTimeOut
,否则核心线程不会因空闲而被回收
maximumPoolSize(最大线程数)
-
线程池允许创建的最大线程数量
-
当工作队列满时,线程池会创建新线程直到达到此限制
keepAliveTime(线程空闲时间)
-
当线程数大于核心线程数时,空闲线程在终止前等待新任务的最长时间
-
仅适用于超出核心线程数的线程
unit(时间单位)
-
keepAliveTime参数的时间单位
-
如TimeUnit.SECONDS、TimeUnit.MILLISECONDS等
workQueue(工作队列)
-
用于保存等待执行的任务的阻塞队列
-
常见实现:
-
ArrayBlockingQueue
:有界队列 -
LinkedBlockingQueue
:无界队列(默认Integer.MAX_VALUE) -
SynchronousQueue
:不存储元素的队列 -
PriorityBlockingQueue
:具有优先级的队列
-
threadFactory(线程工厂)
-
用于创建新线程的工厂
-
可以自定义线程名称、优先级等
handler(拒绝策略)
-
当线程池和工作队列都满时,处理新提交任务的策略
-
内置策略:
-
AbortPolicy
:默认策略,抛出RejectedExecutionException -
CallerRunsPolicy
:由调用线程执行该任务 -
DiscardPolicy
:直接丢弃任务 -
DiscardOldestPolicy
:丢弃队列中最旧的任务并尝试重新提交
-
线程池工作流程
-
提交任务时,如果当前线程数小于corePoolSize,创建新线程执行任务
-
如果线程数达到corePoolSize,新任务被放入工作队列
-
如果工作队列已满且线程数小于maximumPoolSize,创建新线程执行任务
-
如果线程数达到maximumPoolSize且队列已满,触发拒绝策略
代码示例
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;public class ThreadPoolDemo {// 任务计数器private static AtomicInteger taskCount = new AtomicInteger(1);public static void main(String[] args) {// 创建线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(2, // 核心线程数5, // 最大线程数60, // 空闲线程存活时间TimeUnit.SECONDS, // 时间单位new ArrayBlockingQueue<>(10), // 工作队列(容量10)new CustomThreadFactory(), // 自定义线程工厂new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略);// 提交20个任务for (int i = 0; i < 20; i++) {try {executor.execute(new Task("Task-" + i));} catch (RejectedExecutionException e) {System.out.println("任务被拒绝: " + i);}}// 关闭线程池executor.shutdown();}// 自定义任务static class Task implements Runnable {private String name;public Task(String name) {this.name = name;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " 执行 " + name);try {Thread.sleep(1000); // 模拟任务执行} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 完成 " + name);}}// 自定义线程工厂static class CustomThreadFactory implements ThreadFactory {private AtomicInteger threadCount = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r, "CustomThread-" + threadCount.getAndIncrement());thread.setDaemon(false);thread.setPriority(Thread.NORM_PRIORITY);return thread;}}
}
常用预定义线程池
Java通过Executors类提供了几种常用的线程池:
-
newFixedThreadPool:固定大小线程池
-
newCachedThreadPool:可缓存线程池
-
newSingleThreadExecutor:单线程线程池
-
newScheduledThreadPool:定时任务线程池
// 使用示例
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
注意事项
-
合理设置线程池大小,考虑CPU核心数和任务类型(I/O密集型或CPU密集型)
-
避免使用无界队列,可能导致内存溢出
-
根据业务需求选择合适的拒绝策略
-
使用自定义线程工厂便于问题排查和监控
-
正确关闭线程池,调用shutdown()或shutdownNow()
线程池是Java并发编程中的重要组件,合理使用可以显著提高应用程序的性能和稳定性。