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
猜你喜欢
- 一、查看线程的运行状态题目线程有以下6种状态:新建、运行、阻塞、等待、计时等待和终止。new新线程时,线程处于新建 状态。调用start()
- 一、创建maven项目我使用的是汉化的idea可以选择原型,我这里没有选择输入项目名称,完成创建二、配置tomcat选择运行编辑配置点加号找
- java金钱处理方法实例详解在支付行业中,涉及到对金钱的处理比较多。比如分转化成元、费率计算、手续费计算等等。1.分转化成元/** &nb
- 前言Feign是Netflix开源的声明式HTTP客户端,致力于让编写http client更加简单,Feign可以通过声明接口自动构造请求
- 一、异常分类 java异常分为"检查"
- 在搭建Spring Cloud Eureka环境前先要了解整个架构的组成,常用的基础模式如下图:服务提供者:将springboot服务编写好
- 本文实例为大家分享了Java实现简单员工管理系统的具体代码,供大家参考,具体内容如下代码如下:import java.util.*;publ
- 1、代码设计的代理模式代理模式属于构建型模式(Proxy),提供了对目标对象的一种访问方式; 即通过代理对象访问目标对象。这样做的好处是:可
- 本文实例主要进行java Timer(定时调用、固定时间执行)测试,具体实现代码如下。测试1当任务执行时间小于重复执行的间隔时间代码:pub
- Ctrl+1 快速修复Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当
- 1、实现循环队列【OJ链接】循环队列一般通过数组实现。我们需要解决几个问题。(1)数组下标实现循环a、下标最后再往后(offset 小于 a
- 直接插入排序<code class="language-java hljs ">import java.ut
- java掩码 private static String nameMask(String name) throws Exception {
- 一、项目概述之前有不少粉丝私信我说,能不能用Android原生的语言开发一款在手机上运行的游戏呢?说实话,使用java语言直接开发游戏这个需
- 一、静态静态的定时任务可以直接使用注解@Scheduled,并在启动类上配置@EnableScheduling即可@PostMapping(
- hbase是运行在Hadoop上的NoSQL数据库,它是一个分布式的和可扩展的大数据仓库,也就是说HBase能够利用HDFS的分布式处理模式
- /// <summary>/// 获取数据缓存/// </summary>/// <param name=&q
- RocketMQ发送消息我们在使用RocketMQ发送消息时,一般都会使用DefaultMQProducer,类型的代码如下:Default
- 1. 关于POJO类属性为基本类型存在的问题在项目开发中遇到的问题,定义POJO类的时候有些属性定义为了基本数据类型,比如long,shor
- 用Java编写简单的五子棋,供大家参考,具体内容如下前言这两天在空闲时间做了个五子棋项目,分享给大家看一下,界面是这样的:界面很丑我知道,本