线程池的优点:
- 重用线程池中的线程,避免因为线程的创建和销毁带来的性能开销。
- 能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。
- 能够对线程进行简单的管理,并提供定时执行的以及指定间隔循环执行等功能
。
ThreadPoolExecutor
ThreadPoolExecutor是线程池的真正实现,它的构造方法提供了一系列参数来配置线程,构造方法如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数说明
- corePoolSize
线程池的核心数,默认情况下,核心线程会在线程池中一直存活,即使它们处于闲置状态。 - maximumPoolSize
线程池所能容纳的最大线程数,当线程数达到该值时,新任务会被阻塞 - keepAliveTime
非核心线程闲置时的超时时长,超过这个时长,非核心线程会被回收。 - unit
指定keepAliveTime的时间单位,可选有TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分钟)。 - workQueue
线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中。 - threadFactory
用于在线程池中创建新的线程。
ThreadExecutePool执行任务时,大致遵循下面规则:
- 如果线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。
- 如果线程池中的线程数量已经达到或超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行。
- 如果任务队列满,无法插入新任务,线程数量未达到线程池规定最大值,那么会立即启动一个非核心线程来执行任务。
- 如果步骤3中线程数量达到最大值,则拒绝新任务。
常见四类线程池简介与实现
FixedThreadPool
Executor executor = Executors.newFixedThreadPool(3);//参数为线程数
它是一种线程数量固定的线程池,当线程处于空闲状态时,它们不会被回收,除非关闭线程池。
因为它只有核心线程且不会被回收,这意味着它能更快地响应外界请求。
CachedThreadPool
Executor executor1 = Executors.newCachedThreadPool();
它是一种线程数量不定的线程池,它只有非核心线程,最大线程数为Integer.MAX_VALUE。当线程池中的线程都处于活动状态时,会创建新的线程来处理新任务,否则会利用空闲线程处理新任务。超过60s,空闲线程会被回收。
ScheduleThreadPool
Executor executor2= Executors.newScheduledThreadPool(3);//核心线程数
它的核心线程固定的,非核心线程是没有限制的,即maximumPoolSize为Integer.MAX_VALUE,非核心线程空闲时会立即回收,主要用于执行定时任务和具有固定周期的任务。
SingleThreadPool
Executor executor3 = Executors.newSingleThreadExecutor();
该线程内部只有一个核心线程,它确保所有任务都在同一个线程中按顺序执行。SingleThreadPool的意义在一同意所有的外界任务到同一个线程中,使得这些任务不需要处理线程同步的问题。
其它线程
可以通过改变ThreadPoolExecutor的参数按需求构造你的线程。