JAVA——线程池
线程池是一种线程管理机制,它通过预先创建、复用线程来减少频繁创建和销毁线程的开销,提高系统性能和资源利用率。线程池是多线程编程中的核心组件,广泛应用于并发任务处理场景(如 Web 服务器、异步任务处理等)。
线程池代码的实现
java中有一个工具类Executors,通过调用方法返回不用类型的线程池对象。但实际开发中需谨慎使用(部分方法可能导致资源问题)。
1. Executors.newFixedThreadPool(int nThreads)
- 特点:固定核心线程数和最大线程数(
corePoolSize = maximumPoolSize = nThreads
),使用无界队列LinkedBlockingQueue
。- 适用场景:任务数量稳定、耗时适中的场景(如常规业务处理)。
- 注意:无界队列可能导致任务堆积,引发 OOM。
2. Executors.newCachedThreadPool()
- 特点:核心线程数为 0,最大线程数为
Integer.MAX_VALUE
,使用SynchronousQueue
,非核心线程空闲 60 秒后销毁。- 适用场景:大量短期、轻量任务(如临时异步处理)。
- 注意:最大线程数过大,高并发下可能创建过多线程导致 OOM。
3. Executors.newSingleThreadExecutor()
- 特点:核心线程数和最大线程数均为 1,使用无界队列,所有任务串行执行。
- 适用场景:需要任务按顺序执行的场景(如日志写入)。
4. Executors.newScheduledThreadPool(int corePoolSize)
- 特点:支持定时 / 周期性执行任务的线程池(基于
ScheduledThreadPoolExecutor
)。- 适用场景:定时任务(如定时备份、心跳检测)。
//1.获取线程池对象
ExecutorService pool = Executors.newCachedThreadPool();//提交任务
pool.submit(new MyRun());//销毁线程池
pool.shutdown();
public class MyRun implements Runnable{@Overridepublic void run() {for (int i = 0; i < 50; i++){System.out.println(Thread.currentThread().getName() + ":" + i);}}
}
运行结果如下:
当多提交几个任务时:
使用newFixedThreadPool方法设置最大线程数为2再次运行一遍,如果提交任务时,池子没有空闲线程也无法创建新的线程,任务就会排队等待:
- 当核心线程满时,再提交就会排队
- 核心线程满,队伍满,会创建临时线程
- 临时线程也满时,就会触发拒绝策略
自定义线程池
Java 中线程池的核心实现是 java.util.concurrent.ThreadPoolExecutor
,其构造方法定义了线程池的核心参数:
public ThreadPoolExecutor(int corePoolSize, // 核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime, // 非核心线程空闲超时时间TimeUnit unit, // 超时时间单位BlockingQueue<Runnable> workQueue, // 任务阻塞队列ThreadFactory threadFactory, // 线程工厂RejectedExecutionHandler handler // 拒绝策略
) { ... }
corePoolSize
(核心线程数):线程池长期维持的线程数量(即使线程空闲也不会销毁,除非设置了allowCoreThreadTimeOut
)。任务提交时,若当前线程数 < 核心线程数,会优先创建新线程执行任务。
maximumPoolSize
(最大线程数):线程池允许创建的最大线程数(核心线程 + 非核心线程)。当核心线程全忙且任务队列满时,会创建非核心线程处理任务,直到达到此上限。
keepAliveTime
+unit
(空闲超时时间):非核心线程空闲超过该时间后会被销毁,释放资源。可通过allowCoreThreadTimeOut(true)
让核心线程也遵循此规则。
workQueue
(任务队列):用于存储等待执行的任务的阻塞队列(当核心线程全忙时)。常见实现:
ArrayBlockingQueue
:基于数组的有界队列(固定容量);LinkedBlockingQueue
:基于链表的无界队列(默认容量为Integer.MAX_VALUE
);SynchronousQueue
:不存储任务的同步队列(提交任务时必须有线程立即接收);PriorityBlockingQueue
:按优先级排序的无界队列。
threadFactory
(线程工厂):用于创建线程的工厂,可自定义线程名称、优先级、是否为守护线程等。
handler
(拒绝策略):当任务队列满且线程数达到最大线程数时,对新提交任务的处理策略。JDK 默认提供 4 种:
AbortPolicy
(默认):直接抛出RejectedExecutionException
异常;CallerRunsPolicy
:让提交任务的线程自己执行该任务(减缓提交速度);DiscardPolicy
:直接丢弃新任务,不做任何处理;DiscardOldestPolicy
:丢弃队列中最旧的任务,再尝试提交新任务。
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, //核心线程数10, //最大线程数 最大数量>=核心线程数1000, //空闲线程存活最大时间TimeUnit.SECONDS, //时间单位new ArrayBlockingQueue<>(3), //任务队列Executors.defaultThreadFactory(), //线程工厂new ThreadPoolExecutor.AbortPolicy() //任务拒绝策略);