Java线程池实现原理总结
作者:负债程序猿 时间:2023-04-15 02:37:11
要理解实现原理,必须把线程池的几个参数彻底搞懂,不要死记硬背
一、线程池参数
1、corePoolSize(必填):核心线程数。
2、maximumPoolSize(必填):最大线程数。
3、keepAliveTime(必填):线程空闲时长。如果超过该时长,非核心线程就会被回收。
4、unit(必填):指定keepAliveTime的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
5、workQueue(必填):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该队列中。
6、threadFactory(可选):线程工厂。一般就用默认的。
7、handler(可选):拒绝策略。当线程数达到最大线程数时就要执行饱和策略。
说下核心线程数和最大线程数的区别
拒绝策略可选值:
1、AbortPolicy(默认):放弃任务并抛出RejectedExecutionException异常。
2、CallerRunsPolicy:由调用线程处理该任务。
3、DiscardPolicy:放弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
4、DiscardOldestPolicy:放弃队列最早的未处理任务,然后重新尝试执行任务。
二、线程池执行流程
上个流程图,先试着自己看下能不能看懂
简短的总结下线程池执行流程:
1、一个任务提交到线程池后,如果当前的线程数没达到核心线程数,则新建一个线程并且执行新任务,注意一点,这个新任务执行完后,该线程不会被销毁;
2、如果达到了,则判断任务队列满了没,如果没满,则将任务放入任务队列;
3、如果满了,则判断当前线程数量是否达到最大线程数,如果没达到,则创建新线程来执行任务,注意,如果线程池中线程数量大于核心线程数,每当有线程超过了空闲时间,就会被销毁,直到线程数量不大于核心线程数;
4、如果达到了最大线程数,并且任务队列满了,就会执行饱和策略;
三、四种现成的线程池
不想自己new线程池的话,可以用现成的
1、定长线程池(FixedThreadPool)
特点:只有核心线程,线程数量固定,执行完立即回收,任务队列为链表结构的有界队列。
应用场景:控制线程最大并发数
2、定时线程池(ScheduledThreadPool )
特点:核心线程数量固定,非核心线程数量无限,执行完闲置10ms后回收,任务队列为延时阻塞队列。
应用场景:执行定时或周期性的任务。
3、可缓存线程池(CachedThreadPool)
特点:无核心线程,非核心线程数量无限,执行完闲置60s后回收,任务队列为不存储元素的阻塞队列。
应用场景:执行大量、耗时少的任务。
4、单线程化线程池(SingleThreadExecutor)
特点:只有1个核心线程,无非核心线程,执行完立即回收,任务队列为链表结构的有界队列。
应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作、文件操作等。
上述四个线程池虽然方便,但是阿里巴巴规范明确说明不建议使用,因为可能会造成内存溢出,具体原因如下:
FixedThreadPool
和SingleThreadExecutor
:主要问题是堆积的请求处理队列均采用LinkedBlockingQueue,可能会耗费非常大的内存,严重的直接导致内存溢出。CachedThreadPool
和ScheduledThreadPool
:主要问题是它们的最大线程数是Integer.MAX_VALUE,可能会创建数量非常多的线程,严重的直接导致内存溢出。
来源:https://blog.csdn.net/qq_33709582/article/details/113614961
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
springboot项目配置多个kafka的示例代码
Java数组(Array)最全汇总(上篇)
![](https://img.aspxhome.com/file/2023/8/77498_0s.jpg)
深入理解C++中public、protected及private用法
SpringBoot访问静态资源的配置及顺序说明
![](https://img.aspxhome.com/file/2023/3/94203_0s.png)
java使double保留两位小数的多方法 java保留两位小数
Unity Shader实现玻璃材质效果
![](https://img.aspxhome.com/file/2023/7/77227_0s.jpg)
C#创建、部署、调用WebService图文实例详解
![](https://img.aspxhome.com/file/2023/2/113832_0s.png)
c#通过unicode编码判断字符是否为中文示例分享
如何让Spring Rest 接口中路径参数可选
![](https://img.aspxhome.com/file/2023/4/104044_0s.png)
java反射之Method的invoke方法实现教程详解
![](https://img.aspxhome.com/file/2023/2/66632_0s.png)
Android RecyclerView使用ListAdapter高效刷新数据的操作方法
![](https://img.aspxhome.com/file/2023/0/83550_0s.gif)
Java中notify和notifyAll的区别及何时使用
在C#中使用二叉树实时计算海量用户积分排名的实现详解
![](https://img.aspxhome.com/file/2023/1/79101_0s.png)
Windows10 Java环境变量配置过程图解
![](https://img.aspxhome.com/file/2023/4/80834_0s.png)
java调用淘宝api联网查询ip归属地
springboot集成springsecurity 使用OAUTH2做权限管理的教程
![](https://img.aspxhome.com/file/2023/9/101939_0s.jpg)
java单例模式学习示例
Android入门教程之ListView的具体使用详解
![](https://img.aspxhome.com/file/2023/5/122235_0s.jpg)
详解Spring/Spring boot异步任务编程WebAsyncTask
![](https://img.aspxhome.com/file/2023/4/97784_0s.png)
Android Studio设置主题与字体大小图文教程
![](https://img.aspxhome.com/file/2023/8/137428_0s.jpg)