B站 黑马程序员 java八股的视频笔记 自留备忘 如有错误请多多指教。
(一)理论知识
这道题其实就是在问java中线程池的实现类ThreadPoolExecutor,这个类参数最多的构造方法有7个参数。
线程池本质上就是管理一组线程,用来执行提交给线程池的任务。提交任务用的是submit(task)。
corePoolSize设置核心线程数。核心线程执行完任务后仍然需要保留在线程池中的,救急线程执行完没啥用了就不需要保存在线程池中。
核心线程数可以为0,也就是说可以执行完任务都不保留在池中。
workqueue用来缓冲任务,当核心线程都在忙的时候,新来的任务就加到workqueue中。等到有空闲下来的核心线程,就从任务队列中获取任务。
任务队列是有上限的(如果没有上限就会造成内存紧张),核心线程也是有上限的,如果这两个都满了,新来的任务怎么办呢?这时候就交由救急线程来执行。
keepAliveTime生存时间和unit时间单位都是用来控制救急线程的,单位可以秒或毫秒。在这个时间范围内救急线程没有任务可以执行,就把他从线程池中去掉。
当workqueue、核心线程和救急线程都已经满了,再来的新任务怎么办?这时候就要用到handler拒绝策略,是踢掉,报异常,还是替换掉队列中的任务,还是什么都不做。
threadFatory线程工厂不太重要,就是为线程在创建时起名字的。
(二)代码演示
main函数中自定义了一个线程池ThreadPoolExecutor类。然后调用自己写的showState方法查看线程池中的线程和队列状态。(可以暂时不考虑showState方法是怎么实现的,重点是理解线程池)
【初始化线程池】
可以看到定义了核心线程数为2,最大线程数为3,也就是说只能有1个救急线程,救急线程存活时间为0,时间单位为毫秒,工作队列是长度为2的queue,创建线程的名称为myThread+数字。
【添加任务,占满核心线程和工作队列】
准备好线程池后,先添加4个任务到池中:
可以看到先添加的任务1和2已经开始运行,核心线程名额满了,这两个线程的工作时间是一个小时,核心线程短时间内还不能空闲下来。那么任务3和4进入队列等待。
【再新添任务5,救急线程就来救急了】
【将任务5的时间设置为一小时】
救急线程要忙着花一个小时解决任务5,就管不了工作队列中的任务3和4了。
现在,核心线程、救急线程、工作队列都是满的。又来任务了怎么办?
这时候就启动拒绝策略了!总共有以下四种策略:
AbortPolicy:会抛出 RejectedExecutionException 异常。
CallerRunsPolicy:任务不进入线程池执行,交给调用者线程去执行。
DiscardPolicy:丢弃、忽略新来的任务。
DiscardOldestPolicy :新来的任务会替换掉工作队列中最久没被执行的任务。
ps. 等我有时间了就把截图换代码片段,最近时间太紧张。代码还是要亲自运行一下才会理解得更透彻。