多线程学习之线程池
线程状态
| 线程状态 | 具体含义 |
|---|---|
| NEW | 一个尚未启动的线程的状态。也称之为初始、开始状态。线程刚被创建,但是并未启动。还没调用start方法。MyThread t = new MyThread()只有线程对象,没有线程特征。 |
| RUNNABLE | 当我们调用线程对象的start方法,那么此时线程对象进入了RUNNABLE状态。那么此时才是真正的在JVM进程中创建了一个线程,线程一经启动并不是立即得到执行,线程的运行与否要听令与CPU的调度,那么我们把这个中间状态称之为可执行状态(RUNNABLE)也就是说它具备执行的资格,但是并没有真正的执行起来而是在等待CPU的度。 |
| BLOCKED | 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。 |
| WAITING | 一个正在等待的线程的状态。也称之为等待状态。造成线程等待的原因有两种,分别是调用Object.wait()、join()方法。处于等待状态的线程,正在等待其他线程去执行一个特定的操作。例如:因为wait()而等待的线程正在等待另一个线程去调用notify()或notifyAll();一个因为join()而等待的线程正在等待另一个线程结束。 |
| TIMED_WAITING | 一个在限定时间内等待的线程的状态。也称之为限时等待状态。造成线程限时等待状态的原因有三种,分别是:Thread.sleep(long),Object.wait(long)、join(long)。 |
| TERMINATED | 一个完全运行完成的线程的状态。也称之为终止状态、结束状态 |

线程池基本原理和设计思想
基本原理:
线程池可以看做成一个池子,在该池子中存储很多个线程。
线程池存在的意义:
系统创建一个线程涉及到与操作系统交互因此成本是比较高的,当程序中需要创建大量生存期很短暂的线程时,频繁的创建和销毁线程对系统的资源消耗有可能大于业务处理是对系统资源的消耗。针对这一种情况,为了提高性能,我们就可以采用线程池。线程池在启动的时,会创建大量空闲线程,当我们向线程池提交任务的时,线程池就会启动一个线程来执行该任务。等待任务执行完毕以后,线程并不会死亡,而是再次返回到线程池中称为空闲状态。等待下一次任务的执行。
设计思想:
-
准备一个任务容器
-
一次性启动多个(2个)消费者线程
-
刚开始任务容器是空的,所以线程都在wait
-
直到一个外部线程向这个任务容器中扔了一个"任务",就会有一个消费者线程被唤醒
-
这个消费者线程取出"任务",并且执行这个任务,执行完毕后,继续等待下一次任务的到来
方法:
Executors --- 可以帮助我们创建线程池对象
ExecutorService --- 可以帮助我们控制线程池
创建线程池-Executors默认线程池
创建一个默认的线程池
/*** @Author:kkoneone11* @name:MyThreadPoolDemo* @Date:2023/8/28 9:30*/
public class MyThreadPoolDemo {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();executorService.submit(() -> {System.out.println(Thread.currentThread().getName() + "在执行");});executorService.submit(() -> {System.out.println(Thread.currentThread().getName() + "在执行");});executorService.shutdown();}
}
创建线程池-Executors创建指定上限的线程池
创建一个指定的最多线程数量的线程池
public class MyThreadPoolDemo2 {public static void main(String[] args) {//参数不是初始值而是最大值ExecutorService executorService = Executors.newFixedThreadPool(10);ThreadPoolExecutor pool = (ThreadPoolExecutor) executorService;System.out.println(pool.getPoolSize());//0executorService.submit(()->{System.out.println(Thread.currentThread().getName() + "在执行");});executorService.submit(()->{System.out.println(Thread.currentThread().getName() + "在执行");});System.out.println(pool.getPoolSize());//2
// executorService.shutdown();}
}
线程池参数
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略);

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)corePoolSize: 核心线程的最大值,不能小于0
maximumPoolSize:最大线程数,不能小于等于0,maximumPoolSize >= corePoolSize
keepAliveTime: 空闲线程最大存活时间,不能小于0
unit: 时间单位
workQueue: 任务队列,不能为null
threadFactory: 创建线程工厂,不能为null
handler: 任务的拒绝策略,不能为null
非默认任务拒绝策略
RejectedExecutionHandler是jdk提供的一个任务拒绝策略接口,它下面存在4个子类
- ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。是默认的策略。
- ThreadPoolExecutor.DiscardPolicy: 丢弃任务,但是不抛出异常 这是不推荐的做法。
- ThreadPoolExecutor.DiscardOldestPolicy: 抛弃队列中等待最久的任务 然后把当前任务加入队列中。
- ThreadPoolExecutor.CallerRunsPolicy: 调用任务的run()方法绕过线程池直接执行。
注意:明确线程池对多可执行的任务数 = 任务容器容量 + 最大线程数
ThreadPoolExecutor.AbortPolicy 实例1:
public class MyThreadPoolDemo {public static void main(String[] args) {/** 核心线程数量为1 , 最大线程池数量为3, 任务容器的容量为1 ,空闲线程的最大存在时间为20s*/ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 3, 20,TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());// 提交5个任务,而该线程池最多可以处理4个任务,当我们使用AbortPolicy这个任务处理策略的时候,就会抛出异常for(int x = 0; x<5; x++){threadPoolExecutor.submit(()->{System.out.println(Thread.currentThread().getName() +"---》正在执行");});}}
}
有一个任务被抛弃且抛出异常

ThreadPoolExecutor.DiscardPolicy 实例2:
public class ThreadPoolExecutorDemo {public static void main(String[] args) {/*** 核心线程数量为1 , 最大线程池数量为3, 任务容器的容量为1 ,空闲线程的最大存在时间为20s*/ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1 , 3 , 20 , TimeUnit.SECONDS ,new ArrayBlockingQueue<>(1) , Executors.defaultThreadFactory() , new ThreadPoolExecutor.DiscardPolicy()) ;// 提交5个任务,而该线程池最多可以处理4个任务,当我们使用DiscardPolicy这个任务处理策略的时候,控制台不会报错for(int x = 0 ; x < 5 ; x++) {threadPoolExecutor.submit(() -> {System.out.println(Thread.currentThread().getName() + "---->> 执行了任务");});}}
}
丢弃了一个任务但没有报错

ThreadPoolExecutor.DiscardOldestPolicy 实例3:
public class ThreadPoolExecutorDemo {public static void main(String[] args) {/*** 核心线程数量为1 , 最大线程池数量为3, 任务容器的容量为1 ,空闲线程的最大存在时间为20s*/ThreadPoolExecutor threadPoolExecutor;threadPoolExecutor = new ThreadPoolExecutor(1 , 3 , 20 , TimeUnit.SECONDS ,new ArrayBlockingQueue<>(1) , Executors.defaultThreadFactory() , new ThreadPoolExecutor.DiscardOldestPolicy());// 提交5个任务for(int x = 0 ; x < 5 ; x++) {// 定义一个变量,来指定指定当前执行的任务;这个变量需要被final修饰final int y = x ;threadPoolExecutor.submit(() -> {System.out.println(Thread.currentThread().getName() + "---->> 执行了任务" + y);}); }}
}

ThreadPoolExecutor.CallerRunsPolicy 实例4:
public class MyThreadPoolDemo {public static void main(String[] args) {/*** 核心线程数量为1 , 最大线程池数量为3, 任务容器的容量为1 ,空闲线程的最大存在时间为20s*/ThreadPoolExecutor threadPoolExecutor;threadPoolExecutor = new ThreadPoolExecutor(1 , 3 , 20 , TimeUnit.SECONDS ,new ArrayBlockingQueue<>(1) , Executors.defaultThreadFactory() , new ThreadPoolExecutor.CallerRunsPolicy());// 提交5个任务for(int x = 0 ; x < 5 ; x++) {threadPoolExecutor.submit(() -> {System.out.println(Thread.currentThread().getName() + "---->> 执行了任务");});}}
}

相关文章:
多线程学习之线程池
线程状态 线程状态具体含义NEW一个尚未启动的线程的状态。也称之为初始、开始状态。线程刚被创建,但是并未启动。还没调用start方法。MyThread t new MyThread()只有线程对象,没有线程特征。RUNNABLE当我们调用线程对象的start方法,那么此时…...
Elasticsearch基础
1、简介 Elasticsearch是实时的分布式搜索分析引擎,内部使用Lucene做索引与搜索。 何谓实时?新增到 ES 中的数据在1秒后就可以被检索到,这种新增数据对搜索的可见性称为“准实时搜索”。分布式意味着可以动态调整集群规模,弹性扩…...
论文阅读:Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks
前言 要弄清MAML怎么做,为什么这么做,就要看懂这两张图。先说MAML**在做什么?**它是打着Mate-Learing的旗号干的是few-shot multi-task Learning的事情。具体而言就是想训练一个模型能够使用很少的新样本,快速适应新的任务。 定…...
基于Web的旅游推荐网站设计与实现(论文+源码)_kaic
【摘 要】 当前,众所周知的旅游产业已慢慢成为全世界经济领域中最具代表影响力和最大领域的产业之一,互联网的蓬勃发展也为旅游业带来了新的机遇。并且旅游网站已经逐渐成为管理旅游信息的主要模式。因此,开发一个稳定性良好、可用性强的旅游…...
继承AndroidView Model的错误
ViewModelProvider(this)[RegisterViewModel::class.java] 一行简单的代码,总是报这个错误 Caused by: java.lang.NoSuchMethodException: com.xinfa.registerlogin.viewmodel.LoginViewModel. [class android.app.Application] 经过一下午的思索,终于找…...
智慧互联,有序充电--多场景充电
企业微电网能效及充电管理解决方案 安科瑞 崔丽洁 1、企业需求(目的地充电) 站在企业的角度,除了要主动承担碳达峰、碳中和的社会责任,也需要考虑自身的经营和利润,需要结合企业的现状进行改造 企业微电网平台——与…...
yum install libreoffice‘ returned a non-zero
The command ‘/bin/sh -c yum install libreoffice’ returned a non-zero code: 1 1. 异常信息 Is this ok [y/d/N]: Exiting on user command Your transaction was saved, rerun it with:yum load-transaction /tmp/yum_save_tx.2023-08-28.13-42.EftXfl.yumtx The comman…...
Linux知识点 -- 网络基础(一)
Linux知识点 – 网络基础(一) 文章目录 Linux知识点 -- 网络基础(一)一、网络发展二、协议1.OSI七层模型2.TCP/IP五层(或四层)模型 三、网络传输基本流程1.局域网中的两台主机通信流程2.跨网段的两台主机间…...
【leetcode刷题之路】剑指Offer(4)——分治+排序算法+动态规划
文章目录 8 分治算法8.1 【递归】剑指 Offer 07 - 重建二叉树8.2 【递归】【快速幂】剑指 Offer 16 - 数值的整数次方8.3 【递归】剑指 Offer 33 - 二叉搜索树的后序遍历序列8.4 【递归】【分治】剑指 Offer 17 - 打印从1到最大的n位数8.5 【归并排序】【分治】剑指 Offer 51 -…...
美创科技“签”手柠檬文才学堂,共推高校数据安全建设
近日,由柠檬文才学堂联合中国教育在线、东北财经大学网络教育学院共同主办的“三教统筹下高校继续教育数字化转型研讨”顺利召开。 国内高等院校(高职院校)继续教育分管领导,继续教育学院领导及继续教育信息化、教学教务管理、课程…...
【JAVA基础】数据类型,逻辑控制
❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客 🙏 个人名言:不可控之事 乐观面对 😍 系列专栏: 文章目录 数据类型整型变量 int长整型变量 long单精度浮点数 float双精度浮点数 double字符类型 char字节…...
计算机竞赛 基于图像识别的跌倒检测算法
前言 🔥 优质竞赛项目系列,今天要分享的是 基于图像识别的跌倒检测算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/…...
计算机竞赛 基于大数据的股票量化分析与股价预测系统
文章目录 0 前言1 课题背景2 实现效果3 设计原理QTChartsarma模型预测K-means聚类算法算法实现关键问题说明 4 部分核心代码5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于大数据的股票量化分析与股价预测系统 该项目较为新颖…...
input子系统
内核分三层 1、事件处理层 2、核心层 3、设备驱动层 当硬件按下,在设备驱动中触发中断,中断程序会将事件上报给核心层 核心层将事件给事件处理层,最后事件处理层控制app应用层的怎么操作将数据发送到用户空间...
mac 10.13.6安装后开发准备工作
git下载安装 xcode旧版安装搜索 brew国内源安装 brew国内源安装地址2 brew更换源 SwitchHosts github hosts nfts磁盘读写工具 更新ssl证书 证书下载 然后备份一下系统原来的pem文件 cp /etc/ssl/cert.pem /etc/ssl/cert.bak.pem 之后将新下载的pem文件,拷贝到/etc…...
C++ using关键字
C using关键字 using关键字用来简化代码和提高可读性。 using关键字提供了一种灵活的方式,可以在C中导入命名空间和定义别名。 1. 导入命名空间 using namespace 可以将一个命名空间中的所有名称导入到当前作用域中,从而可以直接使用该命名空间中的所…...
让你对es有一个初步的了解
首先es在海量数据的搜索能力非常好,es你可以把他看成一个搜索引擎数据库,他是个非关系型数据库。他的语法有很大的不同,好像都是json风格的。还有一点需要说的就是es 的数据是存在硬盘上的, 我们先来看一下mysql和es的区别吧。一…...
编绎和优化,脚本代码小米加步枪赶超英法美
编程达人:冰冻牡蛎 测试,总结》》 今有空,继续看了一下竹笋大师几天前提出的“使用for循环查找10亿内可被7整除的数的个数”的题目(相关文件:群文件 10亿以内多少个数字可以整除7.7z ) 1. 论输出的exe大小…...
数字电路-二进制学习
什么是二进制? 数字电路 中 只有 高电平 和低电平 就是 1 和0 进位规则是“逢二进一”,借位规则是“借一当二”。 二进制、八进制 、十进制、十六进制 二进制 有两个数来表示 : 0、1 八进制 有8个数来表示 : 0、1、2、3、4、…...
运维Shell脚本小试牛刀(一)
运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 一: Shell中循环剖析 for 循环....... #!/bin/bash - # # # # FILE: countloop.sh # USAGE: ./countloop.sh # DESCRIPTION: # OPTIONS: ------- # …...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
