Java线程池
- 线程池来源于池化技术,如数据库连接池、Http连接池等都是对这个思想的应用。
- 池化技术主要是为了减少每次获取资源的消耗,提高对资源的利用率。
- 线程池提供了一种限制和资源管理(包括执行一个任务)的方式。每个线程池还维护一些基本统计信息,例如已完成任务的数量。
使用线程池的优点
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即执行。
- 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
线程池的种类和适用场景
1. FixedThreadPool(固定大小的线程池)
- 特点:创建一个可重用固定线程数的线程池。
- 适用场景:当已知程序需要执行大量的相关任务,并且可以提前确定所需的线程数量时。
2. CachedThreadPool(缓存线程池)
- 特点:根据需求创建新线程,但在先前构造的线程可用时重用它们。
- 适用场景:执行很多短期异步任务的小程序;如果大量同类任务同时执行,可能会创建大量线程。
3. SingleThreadExecutor(单线程化的线程池)
- 特点:创建一个只有一个工作线程的线程池。
- 适用场景:确保所有任务都在同一个线程中顺序执行,可以保证任务执行顺序和结果的一致性。
4. ScheduledThreadPoolExecutor(定时线程池)
- 特点:创建一个定长线程池,支持定时及周期性任务执行。
- 适用场景:需要执行定时任务或者周期性任务的情况。
线程池的使用
- JDK中线程池的实现类是ThreadPoolExecutor,有四种构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
构造方法中的参数详解
- 1、corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将allowCoreThreadTimeout设置为true时,核心线程超时也会被回收。
- 2、maximumPoolSize(必需):线程池所能容纳的最大线程数,当活跃线程数达到该数值后,后续的新任务将会阻塞
- 3、keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收
- 4、unit(必需)
- 5、workQueue(必需):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该参数中。其采用阻塞队列实现
- threadFactory(可选):线程工厂,用于指定为线程池创建新线程的方式
- handler(可选):拒绝策略。当达到最大线程数时需要执行的拒绝策略