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


猜你喜欢
- 1、在Windows下用CMD netstat命令可以获得当前进程监听端口号的信息,如netstat -ano可以看到IP、port、状态和
- 为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数
- Spring Cloud feign GET请求无法用实体传参代码如下:@FeignClient(name = "eureka-c
- 创建父级项目 只需保留pom.xml文件这里只需搭建一个微服务 其他操作并无<?xml version="1.0"
- 一、作用和区别 break的作用是跳出当前循环块(for、while、do while)或程序块(switch)。在循环块中的作用
- 我这里主要是对串口类的简单使用,实现的功能是以读写方式打开串口,点击发送数据按钮将发送区的数据发送到缓冲区,然后在接收区显示出来,界面如下:
- OO思想现在已经在软件开发项目中广泛应用,其中最重要的一个特性就是继承,最近偶简单的复习了下在C#中涉及到继承这个特性时,所需要用到的关键字
- 目录多通道分离API操作通道合并API操作结果源码多通道分离APIpublic static void split(Mat m, List&
- 本文实例讲述了C#设计模式之Facade外观模式解决天河城购物问题。分享给大家供大家参考,具体如下:一、理论定义外观模式 &nbs
- 一、牵出缓存都有哪些缓存,作用是什么,为什么这么设计1.缓存还在屏幕内的ViewHolder——Sc
- 本文实例为大家分享了C#实现图形界面的时钟的具体代码,供大家参考,具体内容如下秒针有跳跃两个格子问题,主要是算法耗时没考虑在TimeTick
- 通常我们在进行数据绑定的时候,常用的数据源有DataSet、DataTable、BindingList<T>、还有强类型数据源。
- 前言目前互联网公司,大部分项目都是基于分布式,一个项目被拆分成几个小项目,这些小项目会分别部署在不同的计算机上面,这个叫做微服务。当一台计算
- 〇、正则表达式的基本语法符号若只简单匹配固定字符串,则无需任何修饰符,例如:需要匹配字符串 77,则可直接写:new Regex(
- 概述公司的spring boot项目不是使用默认的logback作为日志框架,而是log4j2, 主要原因是logback出现过一个生产问题
- 最近上线的项目中数据库数据已经临近饱和,最大的一张表数据已经接近3000W,百万数据的表也有几张,项目要求读数据(select)时间不能超过
- 在游戏开发中,主角需要通过跑地图来通关升级,本章主要介绍主角的移动和摄像跟随的操作。主角移动角色位移通过主角的骨骼动画控制(后续文章会详细介
- 原生Toast样式自定义Toast样式创建样式所谓自定义一个Toast就是建立一个布局文件,然后使用一个view容器承载,然后显示出来。To
- 前段时间做项目,需要把别人做的hbuilder项目,添加到自己的app中,找了官网、博客,最终终于费了老大的劲实现了,今天就给大家分享一下我
- 之前进行Web开发的时候使用的是myeclipse,但只用过的人都知道,由于其插件太多,而且有很多插件的功能根本就接触不到。所以导致一旦工程