线程池可以根据创建时选择的策略自动处理线程的生命周期。
线程池可以很容易地通过Executors工厂方法来创建。
JDK 中实现 ExecutorService 的类有:
ForkJoinPool,ThreadPoolExecutor、ScheduleThreadPoolExecutor
使用 Executors 类的工程方法来创建 ExecutorService:
- newCachedThreadPool() :创建一个 ExecutorService,该 ExecutorService 根据需要来创建线程,可以重复利用已存在的线程来执行任务。
- newFixedThreadPool(int numberOfThreads) :创建一个可重复使用的、固定线程数量的 ExecutorService。
- newScheduledThreadPool(int corePoolSize):根据时间计划,延迟给定时间后创建 ExecutorService(或者周期性地创建 ExecutorService)。
- newSingleThreadExecutor():创建单个工作线程 ExecutorService。
- newSingleThreadScheduledExecutor():根据时间计划延迟创建单个工作线程 ExecutorService(或者周期性的创建)。
- newWorkStealingPool():创建一个拥有多个任务队列(以便减少连接数)的 ExecutorService。
ExecutorService是一个非常有用的工具,不需要手动创建工作线程。
一个工作线程就是ExecutorService 内部使用的线程。
ExecutorService 管理线程的生命周期。它可以在负载增加的时候增加工作线程。另一方面,在一定周期内,它也可以减少空闲的线程。当我们使用线程池的时候,我们就不再需要考虑线程本身。我们只需要考虑异步处理的任务。
一个任务提交以后,我们可以获取一个未来结果的抽象——Future,只有提交的任务是一个 Callable 时,Future 才有意义,因为 Callable 有输出结果,而 Runnable 没有。
每个线程池由几个模块组成:
- 一个任务队列,
- 一个工作线程的集合,
- 一个线程工厂,
- 管理线程状态的元数据
如果要手动创建一个ThreadPoolExecutor 类的实例,至少需要5个参数:
- int corePoolSize:线程池保存的线程数量。
- int maximumPoolSize:线程的最大数量。
- long keepAlive and TimeUnit unit:超出 corePoolSize大小后,线程空闲的时间到达给定时间后将会关闭。
- BlockingQueue workQueue:提交的任务将被放置在该队列中等待执行。