Java 线程池
这玩意前几天面试被问到了,和数据库连接池搞混了,没答好,随手mark一下吧。
线程池核心类:ThreadPoolExecutor
主要介绍它的核心构造方法
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
简单介绍一下参数:
- corePoolSize:核心线程数,其实就是初始化的最小线程数,但没有把allowCoreThreadTimeOut设置为true时,即使核心线程处于空闲的状态,也不会被回收掉,注意的是并不是一开始创建线程池的时候创建好,而是有任务来的时候才开始创建
- maximumPoolSize:线程池中支持的最大的线程数,但workQueue被设置成无界的时候,此时maximumPoolSize 永远小于corePoolSize,maximumPoolSize 也就无效了。
- keepAliveTime:线程存活时间,指的是默认情况下,但线程数大于corePoolSize的时候,keepAliveTime才会起作用,空闲的线程在达到一定时间后,就会终止被回收,直到线程池中的线程数不大于corePoolSize。但如果我们设置了allowCoreThreadTimeOut为true时,达到keepAliveTime,空闲的线程会被全部回收,直到线程数= 0。
- unit:单位,指的是keepAliveTime的单位
- workQueue:任务堵塞队列,但任务分配达到一定的量,corePoolSize线程已经忙不过来了,此时新的任务就会依次进入任务队列中排序,等待空闲线程来执行。当任务队列满后,还是没有空闲的线程可以执行,线程池中就会开始创建新的线程来执行这些任务。
- threadFactory:创建线程的工厂,负责线程的创建。
- RejectedExecutionHandler:拒绝策略,当并发量很大,maximumPoolSize都已经不够,并且任务队列workQueue也已经爆满,此时该线程池就无法继续工作了,要执行拒绝策略。
银行柜台就是一个多线程处理任务的经典案例:
简单描述一下场景:
1. corePoolSize: 银行窗口1,2,3办理业务
2. maximumPoolSize:银行窗口1,2,3,4,5,其中4,5还未开放使用
3. workQueue:当办理银行业务的人多起来,则有些人需要到等候区排队,目前有3个位置,等候区如果满了,则会打开4,5号窗口,但人实在是太多,银行窗口和等候区都是人,则该银行就无法为其它人提供服务了,当等候区和4,5号窗口空闲了,到达一定时间(keepAliveTime和unit控制),则又会关闭掉4,5号窗口
4.threadFactory:类似做开启窗的功能
5.RejectedExecutionHandler:干的事类似关门,不提供服务了
代码模拟:
public class TestThread {
public static void main(String[] args) {
ExecutorService executorService = new ThreadPoolExecutor(3,
5,
3,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
int index = 1; //控制index来模拟人数进银行办理业务
for (int i = 0; i < index; i++) {
executorService.execute(()->{
System.out.println(Thread.currentThread().getName() + "办理业务");
});
}
executorService.shutdown();
}
}
代码较简单,可自行测试==>
视频学习:
https://www.bilibili.com/video/BV1dt4y1i7Gt?from=search&seid=17243171944504296381