1、什么是线程池?
答:其实说白了,线程池是一种多线程处理方法,帮我们管理线程,避免创建大量的线程增加服务器压力。
其实在面向对象编程中,对象创建和销毁是很费时间的;那么大家就会说,使用线程技术不就好了(ps: 多线程技术主要解决处理器单 元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力),
那么我们举个例子:假设一台服务器完成一项任务的时间为 X
A 创建线程的时间
B 在线程中执行任务的时间,包括线程间同步所需时间
C 线程销毁的时间
X(完成任务的时间)=A+B+C
可以看到A,C是多线程多出的时间,用户希望减少A,C所用的时间,从而减少X的时间,而线程池技术就是缩短这部分时间的技术
2、线程池的原理?
答:创建线程池需要使用 ThreadPoolExecutor 类,它的构造函数参数如下:
ThreadPoolExecutor(int corePoolSize, //核心线程数量 int maximumPoolSize, //最大线程数量 long keepAliveTime, //超出核心线程数量以外的线程空余存活时间 TimeUnit unit, //存活时间的单位 BlockingQueue<Runnable> workQueue, //保存待执行任务的队列 ThreadFactory threadFactory, //创建新线程使用的工厂 RejectedExecutionHandler handler // 当任务无法执行时的处理器 ) {...}
方法如下
``
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//1.当前池中线程比核心数少,新建一个线程执行任务
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//2.核心池已满,但任务队列未满,添加到队列中
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command)) //如果这时被关闭了,拒绝任务
reject(command);
else if (workerCountOf(recheck) == 0) //如果之前的线程已被销毁完,新建一个线程
addWorker(null, false);
}
//3.核心池已满,队列已满,试着创建一个新线程
else if (!addWorker(command, false))
reject(command); //如果创建新线程失败了,说明线程池被关闭或者线程池完全满了,拒绝任务
}
``
我们要了解线程池的原理,我们说打比方简单一点
线程比作员工,线程池比作一个团队,核心池比作团队中核心团队员工数,核心池外的线程比作外包员工
- 假如团队有了新需求, 先看核心员工数有没有超过最大核心员工数,如果没有超过,就再找一个人进来
- 如果最大核心员工已经满名额了,人事不准再进人了,那这个需求只好攒着,放到待完成任务列表吧
- 如果待完成任务列表也满了,核心员工根本无法完成这么多任务,就只能再找个外包公司了
- 如果核心员工 + 外包员工的数量已经是团队最多能承受人数了,就只能执行handler处理被拒绝的任务。