4.1. FixedThreadPool
FixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待
固定大小的线程池使用无界队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为 Integer.MAX_VALUE)。使用无界队列作为工作队列会对线程池带来如下影响:
- 线程池中的线程数达到corePoolSize后,新任务将在无界队列中等待,因此线程池中的线程数不会超过corePoolSize。
- 由于1,使用无界队列时maximumPoolSize将是一个无效参数。
- 由于1和2,使用无界队列时keepAliveTime将是一个无效参数。
- 由于使用无界队列,运行中的FixedThreadPool(未执行方法shutdown()或 shutdownNow())不会拒绝任务(不会调用RejectedExecutionHandler.rejectedExecution方法)。
- 核心线程数和最大线程数一样,即其线程全为核心线程,
- 如果任务提交速度持续大于任务处理速度,会造成队列大量阻塞。因为队列很大,很有可能在拒绝策略前,内存溢出。是其劣势;
- FixedThreadPool 的任务执行是无序的;
- 适用于任务量已知,相对耗时的任务
4.2. CachedThreadPool
CachedThreadPool:创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程。
- 核心线程数为0
- maximumPoolSize(最大线程数) = Integer.MAX_VALUE,即线程数量几乎无限制,即maximumPool是无界的
- workQueue 为 SynchronousQueue 同步队列,不存储元素的阻塞队列,这个队列类似于一个接力棒,入队出队必须同时传递,因为 CachedThreadPool 线程创建无限制,不会有队列等待,所以使用 SynchronousQueue
- 如果主线程提交任务的速度高于线程处理任务的速度时,CachedThreadPool会不断创建新线程。极端情况下, CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源。
- 适用场景:快速处理大量耗时较短的任务,如 Netty 的 NIO 接受请求时,可使用 CachedThreadPool。
4.3. SingleThreadExecutor
SingleThreadExecutor:它只会用唯一的工作线程来执行任务,它可以保证先进先出的执行顺序。
- 核心线程数和最大线程数都为1
- 阻塞队列是无界队列LinkedBlockingQueue,队列的最大容量为 Integer.MAX_VALUE
- 适用于按照顺序执行的任务
4.4. ScheduledThread
ScheduledThreadPool:创建一个可以执行延迟任务的线程池。
- 支持定时以及周期性的任务执行