一. ThreadPoolExecutor的构造参数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
TimeUnit unit, BlockingQueue<runnable> workQueue,
ThreadFactory threadFactory,RejectedExecutionHandler handler)
ThreadPoolExecutor
一共有7个参数,下面是每个参数的意义
参数名 | 类型 | 说明 |
---|---|---|
corePoolSize | int | 核心线程数 |
maximumPoolSize | int | 线程池中最大线程数 |
keepAliveTime | long | 除核心线程外,其他线程空闲时间, 配置了allowCoreThreadTimeOut之后 该属性也可作用于很线程 |
unit | TimeUnit | 和keepAliveTime搭配使用 |
workQueue | BlockingQueue | 工作队列 |
threadFactory | ThreadFactory | 线程创建工厂 |
handler | RejectedExecutionHandler | 线程池拒绝策略 |
二. corePoolSize和maximumPoolSize
corePoolSize和maximumPoolSize这两个参数使用来控制线程池大小的参数,ThreadPoolExecutor
会根据这两个参数的值来动态的调整线程池的大小,将这两个属性的值设置成一样,就会得到一个固定大小的线程池。ThreadPoolExecutor
在接受一个任务时主要分为三个步骤,如下图。
graph LR
Start(Submit Task)-->core{"WorkSize>corePollSize"}
core--是-->queue{"WorkQueue is full"}
queue--是-->maxpool{"WorkSize>maxPoolSize"}
maxpool--是-->Reject
core--否-->new("Execute Task ")
queue--否-->addToQueue("addToQueue ")
maxpool--否-->newTask("Execute Task ")
- 通过
public void execute(Runnable command)
方法来提交一个一个任务 - 判断当前工作线程数是否大于核心线程数,否则创建一个新的线程执行该任务
- 如果大于当前核心线程则尝试放入工作队列中进行等待
- 如果工作队列已满,则判断工作线程数是否大于最大线程数,是则根据
RejectedExecutionHandler
拒绝该任务,否则创建一个新的线程执行该任务
总结上面的流程我们可以看出,线程池方式的优点:
- 合理控制并发的线程数,将执行的工作线程数控制在核心线程数,合理利用系统资源
- 合理管理线程的创建和销毁,我们知道线程的创建是十分消耗系统资源的,而通过线程池的方式,可以不必频繁的创建线程,可以利用线程池中空闲的线程资源来执行任务。在系统空闲线程不够的情况下才会去创建新的线程,这样在密集任务执行时可以合理利用线程资源。在默认情况下,只有新任务进来时,才会去创建核心线程,不过你可以通过
public boolean prestartCoreThread()
和public int prestartAllCoreThreads()
去创建一个或所有核心线程。
三. JDK内置的集中线程池
在java.util.concurrent.Executors
中JAVA
已经为我们实现好了集中常用的线程池.。
-
FixedThreadPool
创建一个固定线程数的线程池,其实就是将ThreadPollExecutor
的核心线程数和最大线程数两个属性设置成一样的值,可以用来控制并发数.
public static ExecutorService newFixedThreadPool(int nThreads);
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
-
CachedThreadPool创建一个可缓存的线程池,在收到一个任务时,会在空闲的线程中去一个出来执行任务,如果没有则会创建一个新的线程去执行任务,适合短期的大量的异步任务。CachedThreadPool的核心线程数设置的为0,每次都是从工作队列中去执行任务,代码中设置的超时时间是60秒,这样在超过60秒之后,空闲的线程就会被回收,不会出现占用系统资源的情况。
-
public static ExecutorService newCachedThreadPool(); public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
-
SingleThreadExecutor
创建一个只有一个工作线程的线程池,线程池中只有一个线程去执行任务,可以控制任务的顺序性。public static ExecutorService newSingleThreadExecutor(); public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);
-
SingleThreadScheduledExecutor
创建只有一个工作线程的可执行周期性任务的线程池,它除了可以像其他的线程池一样可以执行异步任务,也支持执行定时任务。public static ScheduledExecutorService newSingleThreadScheduledExecutor(); public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory);