共计 3119 个字符,预计需要花费 8 分钟才能阅读完成。
所谓的线程池的 7 大参数是指,在应用 ThreadPoolExecutor 创立线程池时所设置的 7 个参数,如以下源码所示:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {//...}
这 7 个参数别离是:
- corePoolSize:外围线程数。
- maximumPoolSize:最大线程数。
- keepAliveTime:闲暇线程存活工夫。
- TimeUnit:工夫单位。
- BlockingQueue:线程池工作队列。
- ThreadFactory:创立线程的工厂。
-
RejectedExecutionHandler:回绝策略。
参数 1:corePoolSize
外围线程数:是指线程池中长期存活的线程数。
这就好比现代大户人家,会长期雇佣一些“短工”来给他们干活,这些人个别比较稳定,无论这一年的活多活少,这些人都不会被解雇,都是长期生存在大户人家的。
参数 2:maximumPoolSize
最大线程数:线程池容许创立的最大线程数量,当线程池的工作队列满了之后,能够创立的最大线程数。
这是现代大户人家最多能够雇佣的人数,比方某个节日或大户人家有人过寿时,因为活太多,仅靠“短工”是完不成工作,这时就会再招聘一些“短工”一起来干活,这个最大线程数就是“短工”+“短工”的总人数,也就是招聘的人数不能超过 maximumPoolSize。
注意事项
最大线程数 maximumPoolSize 的值不能小于外围线程数 corePoolSize,否则在程序运行时会报 IllegalArgumentException 非法参数异样,如下图所示:
参数 3:keepAliveTime
闲暇线程存活工夫,当线程池中没有工作时,会销毁一些线程,销毁的线程数 =maximumPoolSize(最大线程数)-corePoolSize(外围线程数)。
还是以大户人家为例,当大户人家比较忙的时候就会雇佣一些“短工”来干活,但等干完活之后,不忙了,就会将这些“短工”解雇掉,而 keepAliveTime 就是用来形容没活之后,短工能够在大户人家待的(最长)工夫。
参数 4:TimeUnit
工夫单位:闲暇线程存活工夫的形容单位 ,此参数是配合参数 3 应用的。
参数 3 是一个 long 类型的值,比方参数 3 传递的是 1,那么这个 1 示意的是 1 天?还是 1 小时?还是 1 秒钟?是由参数 4 说了算的。
TimeUnit 有以下 7 个值:
- TimeUnit.DAYS:天
- TimeUnit.HOURS:小时
- TimeUnit.MINUTES:分
- TimeUnit.SECONDS:秒
- TimeUnit.MILLISECONDS:毫秒
- TimeUnit.MICROSECONDS:奥妙
-
TimeUnit.NANOSECONDS:纳秒
参数 5:BlockingQueue
阻塞队列:线程池寄存工作的队列,用来存储线程池的所有待执行工作。
它能够设置以下几个值: - ArrayBlockingQueue:一个由数组构造组成的有界阻塞队列。
- LinkedBlockingQueue:一个由链表构造组成的有界阻塞队列。
- SynchronousQueue:一个不存储元素的阻塞队列,即间接提交给线程不放弃它们。
- PriorityBlockingQueue:一个反对优先级排序的无界阻塞队列。
- DelayQueue:一个应用优先级队列实现的无界阻塞队列,只有在提早期满时能力从中提取元素。
- LinkedTransferQueue:一个由链表构造组成的无界阻塞队列。与 SynchronousQueue 相似,还含有非阻塞办法。
- LinkedBlockingDeque:一个由链表构造组成的双向阻塞队列。
比拟罕用的是 LinkedBlockingQueue,线程池的排队策略和 BlockingQueue 非亲非故。
参数 6:ThreadFactory
线程工厂:线程池创立线程时调用的工厂办法,通过此办法能够设置线程的优先级、线程命名规定以及线程类型(用户线程还是守护线程)等。
线程工厂的应用示例如下:
public static void main(String[] args) {
// 创立线程工厂
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
// 创立线程池中的线程
Thread thread = new Thread(r);
// 设置线程名称
thread.setName("Thread-" + r.hashCode());
// 设置线程优先级(最大值:10)thread.setPriority(Thread.MAX_PRIORITY);
//......
return thread;
}
};
// 创立线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 0,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
threadFactory); // 应用自定义的线程工厂
threadPoolExecutor.submit(new Runnable() {
@Override
public void run() {Thread thread = Thread.currentThread();
System.out.println(String.format("线程:%s,线程优先级:%d",
thread.getName(), thread.getPriority()));
}
});
}
以上程序的执行后果如下:
从上述执行后果能够看出,自定义线程工厂起作用了,线程的名称和线程的优先级都是通过线程工厂设置的。
参数 7:RejectedExecutionHandler
回绝策略:当线程池的工作超出线程池队列能够存储的最大值之后,执行的策略。
默认的回绝策略有以下 4 种:
- AbortPolicy:回绝并抛出异样。
- CallerRunsPolicy:应用以后调用的线程来执行此工作。
- DiscardOldestPolicy:摈弃队列头部(最旧)的一个工作,并执行当前任务。
- DiscardPolicy:疏忽并摈弃当前任务。
线程池的默认策略是 AbortPolicy 回绝并抛出异样。
总结
本文介绍了线程池的 7 大参数:
- corePoolSize:外围线程数,线程池失常状况下放弃的线程数,大户人家“短工”的数量。
- maximumPoolSize:最大线程数,当线程池忙碌时最多能够领有的线程数,大户人家“短工”+“短工”的总数量。
- keepAliveTime:闲暇线程存活工夫,没有活之后“短工”能够生存的最大工夫。
- TimeUnit:工夫单位,配合参数 3 一起应用,用于形容参数 3 的工夫单位。
- BlockingQueue:线程池的工作队列,用于保留线程池待执行工作的容器。
- ThreadFactory:线程工厂,用于创立线程池中线程的工厂办法,通过它能够设置线程的命名规定、优先级和线程类型。
- RejectedExecutionHandler:回绝策略,当任务量超过线程池能够保留的最大工作数时,执行的策略。
是非审之于己,毁誉听之于人,得失安之于数。
公众号:Java 面试真题解析
面试合集:https://gitee.com/mydb/interview