2023面试系列 线程池用过居然不知道底层原理,啥也不是!

1.为什么使用线程池:


1. 减少线程频繁的创建跟销毁带来的性能消耗

2. 便于管理线程

3. 提高响应速度(不用等待线程创建)

4. 能提供更多的功能

2.线程池的创建方式:


通过Executors创建

通过ThreadPoolExecutor创建(提倡)

3.线程池的参数说明:


corePoolSize

MaxinumPoolSize

keepAliveTime

TimeUint unit

扫描二维码关注公众号,回复: 16574216 查看本文章

BlockingQueue<Runnable> workQueue,

RejectedExecutionHandler handler

4.线程池的流程:


-当有任务的时候,如果当前线程数小于核心线程数,那么先创建核心线程数去执行任务。

当线程数已达到核心线程数时,则将任务加入到阻塞队列中去。当阻塞队列满了之后,如果当前线程数大于核心线程数,小于最大线程数时,则创建非核心线程数去执行。如果不满足,则执行拒绝策略

线程池的状态:

Running-ShowDown-ShowDownNow-Stop-Tidying-Terminated

5.线程池的几个重要方法来深入底层原理


-excute(Runnable command)
-addWorker(Runnable fistTask,boolean core)


小结:


--addWorker方法有三种不同的参数调用,在增加任务的过程中,对线程池状态跟线程数进行了多次判断

addWorker(first,true):小于核心线程数,创建核心线程去 执行任务

addWorker(null,false):添加到阻塞队列中去,线程数<最大线程数

addWorker(first,false):阻塞队列已满,创建新的非核心线程去执行任务

-runWorker(Worker w)
-getTask()
-processWorkerExit(Worker w,boolean completedAbruptly)

6.线程池技术亮点:


线程池通过使用CAS跟AutomicInteger来改变线程数量跟线程状态,核心参数用Volatile来修饰,同时使用Condition、ReentrantLock对创建线程的过程,线程池状态的改变,工作任务数量的改变(添加跟删除)等,来通过allowCoreThreadTimeOut || wc > corePoolSize来判断使用poll还是take方法或者任务,Worker同时也继承了AQS(不可重入,线程运行时就不会中断)

7.使用线程池需要注意的点:


1.合理的设置核心线程、最大线程数,充分利用资源,同时也要避免资源的浪费。

2.选择好拒绝策略,注意抛出异常的处理。

3.不合理的设置阻塞队列,选用了LinkedBlockedQueue导致线程池溢出

4.重复创建的线程池,记得showdown

5.根据业务需要,设置allowCoreThreadTimeOut(true),回收被阻塞的核心线程

8. 简单自定义线程池名字:区分不同业务下的线程池


9. 简单自定义拒绝策略

10. 留给小作业

阻塞队列满了,怎么处理呢?
 

猜你喜欢

转载自blog.csdn.net/weixin_42450130/article/details/132645241