java线程池的参数详解

java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释。
在这里插入图片描述

从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。下面会对这7个参数一一解释。

参数名 含义 注意要点
corePoolSize 核心线程数,线程池中维护的最小线程数量(包含活跃和空闲的线程数量) 1、线程池创建后,不是默认就会创建corePoolSize大小的线程数,而是有任务提交了才会开始创建线程
maximumPoolSize 最大线程数,线程池允许创建的最大线程数量 1、maximumPoolSize 一般大于corePoolSize的值
2、如果maximumPoolSize = corePoolSize,那么该线程池是固定大小的线程池
keepAliveTime 线程池中空闲的线程保活时间 1、默认情况下(allowCoreThreadTimeOut = false),只有当线程池中的运行线程数量超过了corePoolSize时,keepAliveTime才会起作用,即keepAliveTime只对超出corePoolSize部分的线程起作用(举例说明:corePoolSize = 10,当前有15个线程在运行,此时运行线程超过了核心线程数,当线程执行完任务之后处于空闲时,当时间达到keepAliveTime的临界值后,有5个线程会被销毁,线程池中最后只会有10个可用的线程数)
2、如果线程池设置了allowCoreThreadTimeOut = true,那么keepAliveTime同样对核心线程启作用,即核心线程中线程空闲下来后,也会在时间达到keepAliveTime的临界值后销毁,线程池中的线程数可以为0
unit 保活时间单位(例如:秒,毫秒等) TimeUnit.DAYS; // 天
TimeUnit.HOURS;// 小时
TimeUnit.MINUTES; // 分
TimeUnit.SECONDS;// 秒
TimeUnit.MILLISECONDS;// 毫秒
TimeUnit.MICROSECONDS;// 微秒
TimeUnit.NANOSECONDS;// 纳秒
workQueue 任务阻塞队列,当任务数超过当前线程池中的核心线程数量时,切队列未满,需要执行的任务会优先被放入到阻塞队列中进行等待 新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:详情见下方
threadFactory 线程工厂对象,用来创建新的线程实例 创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等
handler 拒绝策略 拒绝执行处理策略 当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:详情见下方

workQueue 工作队列
①ArrayBlockingQueue

基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

②LinkedBlockingQuene

基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

③SynchronousQuene

一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

④PriorityBlockingQueue

具有优先级的无界阻塞队列,优先级通过参数Comparator实现(该队列使用极少)。

拒绝处理策略方针:
1.CallerRunsPolicy 该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。如果任务添加失败,且线程池未关闭的情况下,那么调用线程(主线程)自己会调用执行器中的execute()方法来执行该任务
2.AbortPolicy 线程池默认的策略方针,如果有任务添加失败,则会丢弃掉该任务,并抛出RejectedExecutionException异常。
3.DiscardPolicy 如果任务添加失败,则会丢弃掉该任务,且不抛出任何异常。
4.DiscardOldestPolicy 如果任务添加失败,会将队列中最早入队的任务移除poll(),再尝试添加,如果还失败,则会按此策略不断的重试
5.自定义策略方针 如果以上的策略方针都不能满足要求,那么可以自定义符合场景的policy;实现RejectedExecutorHandler接口中的rejectedExecution()方法即可

文章来源参考
https://blog.csdn.net/ye17186/article/details/89467919
https://blog.csdn.net/u012253957/article/details/102967238?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-1&spm=1001.2101.3001.4242

猜你喜欢

转载自blog.csdn.net/weixin_44887276/article/details/115162666