线程池
什么是线程池?
线程池:一种基于池化思想管理和使用线程的机制
线程池常用类和接口
ExecutorService
接口:进行线程池的操作访问Executors
类:创建线程池的工具类ThreadPoolExecutor
及其子类:封装线程池的核心参数和运行机制
线程池常见的方法:
- 执行无参返回值的线程任务:
void execute(Runnable command);
- 提交有返回值的线程任务:
Future<T> submit(Callable<T> task);
- 关闭线程池:
void shutdown();
或shutdownNow();
- 等待线程池关闭:
boolean awaitTermination(long timeout,TimeUnit unit);
线程池执行流程
- 提交一个新的线程任务,线程池判断池中是否存在空闲线程;如果存在分配空闲线程执行线程任务;
- 如果线程池中没有空闲的线程,则判断核心线程数是否超出设定,未超出则创建核心线程,用于执行新提交的线程任务;
- 如果已超出核心线程数,则往工作队列中存放(工作队列:先进先出),当出现空闲线程时,从工作队列中依次取出线程任务;
- 如果工作队列已经存满,则判断最大线程数是否超出,未超出最大线程数,则创建非核心线程,执行线程任务;
- 如果已达到了最大线程数,则启动拒绝策略;
线程数的配置参数
corePoolSize
线程池核心线程数:可以理解为线程池维护的最小线程数,核心线程创建后不会被回收。大于核心线程数的吸纳成,在空闲时间超过keepAliveTime
后会被回收
maximumPoolSize
线程池最大线程数:线程池允许创建的最大线程数量(包含核心线程池数量)
keepAliveTime
非核心线程存活时间:当一个可被回收的线程的空闲时间大于keepAliveTime
就会被回收
TimeUnit
时间单位:参数keepAliveTime
的时间单位
BlockingQueue
阻塞工作队列:用于存储等待执行的任务
ThreadFactory
线程工厂:用于创建线程,以及自定义线程名称,需要实现ThreadFactory
接口
RejectedExecutionHandler
拒绝策略:当线程池中的线程耗尽,并且工作队列已满时,新提交的任务,将会启动拒绝策略处理
线程池的分类
-
FixedThreadPool
:线程数固定的线程池通过
Executors.newFixedThreadPool(n);
方法创建// 创建有十个线程的线程池 Executors.newFixedThreadPool(10); // Executors.newFixedThreadPool(n)方法源码 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
通过源码,FixedThreadPool线程池的核心线程数和最大线程数都是传入的参数,所以是固定线程数的线程池;
-
CacheThreadPool
:线程数根据任务动态调整的线程池通过
Executors.newCachedThreadPool();
方法创建// 创建一个CacheThreadPool线程池 Executors.newCachedThreadPool(); // 源码 public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
通过源码,CacheThreadPool线程池的核心线程数为0,最大线程数为
Integer
的最大值,非核心线程的存活时间为60s
-
SingleThreadPool
:仅提供一个单线程的线程池通过
Executors.*newSingleThreadExecutor*();
方法创建// 创建一个SingleThreadPool线程池 Executors.newSingleThreadExecutor(); // 源码 public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
通过源码,SingleThreadPool线程池的核心线程数和最大线程数都为1,其他线程的存储时间为0
-
ScheduledThreadPool
:能实现定时、周期性任务的线程池通过
Executors.newScheduledThreadPool(n);
方法创建// 创建一个ScheduledThreadPool线程池 Executors.newScheduledThreadPool(10); // 源码 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } ⬇⬇⬇⬇⬇⬇ // new ScheduledThreadPoolExecutor(corePoolSize);方法源码 public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
通过源码,ScheduledThreadPool线程池的核心线程数为传入的参数,最大线程数为
Integer
类型的最大值,非核心线程的存活时间为0,空闲立马被回收