线程池底层原理
线程池底层原理
ThreadPoolExecutor
参数
-
corePoolSize(必填) : 核心线程数
-
maximumPoolSize(必填):最大线程数
-
keepAliveTime(必填):线程空闲时长。如果超过该时长,非核心线程就会被回收。
-
unit(必填):指定keepAliveTime的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)
-
workQueue(必填):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该队列中。
-
threadFactory(可选):线程工厂。一般就用默认的。
-
handler(可选):拒绝策略。当线程数达到最大线程数时就要执行饱和策略。
拒绝策略可选值
1、AbortPolicy(默认):放弃任务并抛出RejectedExecutionException异常。
2、CallerRunsPolicy:由调用线程处理该任务。
3、DiscardPolicy:放弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
4、DiscardOldestPolicy:放弃队列最早的未处理任务,然后重新尝试执行任务。
线程池运行机制
- 一个任务提交到线程池后,如果当前的线程数没达到核心线程数,则新建一个线程并且执行新任务,注意一点,这个新任务执行完后,该线程不会被销毁
- 如果达到了,则判断任务队列满了没,如果没满,则将任务放入任务队列;
- 如果满了,则判断当前线程数量是否达到最大线程数,如果没达到,则创建新线程来执行任务,注意,如果线程池中线程数量大于核心线程数,每当有线程超过了空闲时间,就会被销毁,直到线程数量不大于核心线程数;
- 如果达到了最大线程数,并且任务队列满了,就会执行饱和策略;
总结公式:
存活任务数 <= 核心线程数时,线程池中工作线程数 = 存活任务数
核心线程数 + 队列容量 < 存活任务数 <= 最大线程数 + 队列容量时,工作线程数 = 存活任务数 - 队列容量
存放线程对象的容器为什么使用HashSet?
HashSet基于HashMap来实现的,基于hash函数和负载因子的设计可以减少hash碰撞的概率,这些操作的时间复杂度都是O(1)的,而且线程池里的线程对于顺序和优先级都没有要求,还可以自动去重。

浙公网安备 33010602011771号