线程池相关解读

不推荐使用Executors创建线程池使用
ExecutorService threadPool = Executors.newFixedThreadPool(5); //固定的线程数
ExecutorService threadPool = Executors.newSingleThreadExecutor(); //固定一个线程数
ExecutorService threadPool = Executors.newCachedThreadPool(); //动态添加线程数

上述三种方式,通过new ThreadPoolExecutor创建,底层会创建一个无线的阻塞队列,当数量过大时,容易引起OOM。

线程池创建的方式:

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

corePoolSize: 核心线程数量(固定存在的线程数量,体现了线程池可一次数量的线程数量)io密集型:核心线程数=cpu核数2、cpu密集型:核心线程数=cpu核数+1
maximumPoolSize:最大线程数量 io密集型:核心线程数=cpu核数
4、cpu密集型:cpu核数*2
keepAliveTime:非核心线程的空闲的存活时间(针对临时线程)
unit: 时间单位(针对临时线程)
workQueue:工作队列(阻塞队列,当核心线程数量已满,则多余对的任务先放置在队列中等待,如果阻塞队列已满,则再次创建临时线程进行处理,临时线程数量=最大线程数量-核心线程数量,优先处理队列中的线程)
ThreadFactory:线程工厂(创建线程,一般是默认的线程工厂)
defaultHandler : 拒绝策略(当核心线程数、临时线程数、阻塞队列都已满时触发)
四种默认拒绝策略:
1.AbortPolicy(默认):当工作队列已满且无法再添加新任务时,抛出RejectExecutionException异常。
2.CallerRunPolicy:当工作队列已满且无法再添加新任务时,由提交任务的线程来执行该任务,也就是说,任务将在提交线程的上下文中执行。
3.DiscardOldestPolicy:当工作队列已满且无法再添加新任务时,丢弃队列中最早的任务(即等待时间最长的任务),然后尝试重新提交新任务。
4.DiscardPolicy:当工作队列已满且无法再添加新任务时,直接迭起新任务,不做任何处理。
注:可自定义拒绝策略。

注:
1.创建线程池时,不创建线程(tomcat创建),当有任务时,才创建线程。当核心线程全部创建完毕后,后续的任务都会放置至阻塞队列中,后续保留核心线程数的线程,会无限阻塞的从阻塞队列中获取任务。(销毁或保留不区分先后创建的线程)
2.如果线程运行时报错,当前线程会销毁,并重新创建线程会处理其他任务,可以通过重写afterExecute方法进行处理,也可以设置统一异常处理:
thread.setUncaughtExceptionHandler。
3.线程池如果关闭,则不会处理新的任务,正在执行中的任务会继续进行完毕,如果正在获取阻塞队列中的任务,shutdown可以获取阻塞队列中的任务,shutdownnow无法执行任务.

480adc00a97acc640f7049379b3b85e6

线程池的状态:
RUNNING:默认状态,可以正常的接收任务、执行任务、处理工作队列的任务;
SHUTDOWN:不接收新任务,但是可以正常的处理工作队列任务;
STOP:不接收任务,也不会继续处理的等待队列中的任务,而且中断正在执行的任务,工作队列的任务直接作为返回值,返回结果就是阻塞队列中没处理完的任务;
TIDYING:所有任务都已经结束,工作线程数为0,是过度状态,将会运行terminated()把线程池状态修改为TERMINATED;
TERMINATED:terminated()这个勾子函数被调用执行完毕,线程池就会终止。

状态之间的转换:
RUNNING >>> SHUTDOWN : 当调用了shutdown()方法,线程池会转为SHUTDOWN状态;
RUNNING或者SHUTDOWN >>> STOP :当调用了shundownNow()方法发,线程池就会转为STOP状态;
SHUTDOWN >>> TIDYING : 当等待队列为空,工作线程数为0,线程池就会从SHUTDOWN转为TIDYING;
STOP >>> TIDYING : 当等待队列为空,线程池就会从STOP转为TIDYING
TIDYING >>> TERMINATED : 当terminated()这个勾子函数被调用,线程池就会从TIDYING 转为 TERMINATED状态。

posted @ 2025-08-27 15:16  唐老师很无聊  阅读(9)  评论(0)    收藏  举报