当前位置: 首页 > news >正文

多线程学习之线程池

线程状态

线程状态具体含义
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一个完全运行完成的线程的状态。也称之为终止状态、结束状态

线程池基本原理和设计思想

基本原理:

线程池可以看做成一个池子,在该池子中存储很多个线程。

线程池存在的意义:

系统创建一个线程涉及到与操作系统交互因此成本是比较高的,当程序中需要创建大量生存期很短暂的线程时,频繁的创建和销毁线程对系统的资源消耗有可能大于业务处理是对系统资源的消耗。针对这一种情况,为了提高性能,我们就可以采用线程池。线程池在启动的时,会创建大量空闲线程,当我们向线程池提交任务的时,线程池就会启动一个线程来执行该任务。等待任务执行完毕以后,线程并不会死亡,而是再次返回到线程池中称为空闲状态。等待下一次任务的执行。

设计思想:

  1. 准备一个任务容器

  2. 一次性启动多个(2个)消费者线程

  3. 刚开始任务容器是空的,所以线程都在wait

  4. 直到一个外部线程向这个任务容器中扔了一个"任务",就会有一个消费者线程被唤醒

  5. 这个消费者线程取出"任务",并且执行这个任务,执行完毕后,继续等待下一次任务的到来

方法:

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一个尚未启动的线程的状态。也称之为初始、开始状态。线程刚被创建&#xff0c;但是并未启动。还没调用start方法。MyThread t new MyThread()只有线程对象&#xff0c;没有线程特征。RUNNABLE当我们调用线程对象的start方法&#xff0c;那么此时…...

Elasticsearch基础

1、简介 Elasticsearch是实时的分布式搜索分析引擎&#xff0c;内部使用Lucene做索引与搜索。 何谓实时&#xff1f;新增到 ES 中的数据在1秒后就可以被检索到&#xff0c;这种新增数据对搜索的可见性称为“准实时搜索”。分布式意味着可以动态调整集群规模&#xff0c;弹性扩…...

论文阅读:Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks

前言 要弄清MAML怎么做&#xff0c;为什么这么做&#xff0c;就要看懂这两张图。先说MAML**在做什么&#xff1f;**它是打着Mate-Learing的旗号干的是few-shot multi-task Learning的事情。具体而言就是想训练一个模型能够使用很少的新样本&#xff0c;快速适应新的任务。 定…...

基于Web的旅游推荐网站设计与实现(论文+源码)_kaic

【摘 要】 当前&#xff0c;众所周知的旅游产业已慢慢成为全世界经济领域中最具代表影响力和最大领域的产业之一&#xff0c;互联网的蓬勃发展也为旅游业带来了新的机遇。并且旅游网站已经逐渐成为管理旅游信息的主要模式。因此&#xff0c;开发一个稳定性良好、可用性强的旅游…...

继承AndroidView Model的错误

ViewModelProvider(this)[RegisterViewModel::class.java] 一行简单的代码&#xff0c;总是报这个错误 Caused by: java.lang.NoSuchMethodException: com.xinfa.registerlogin.viewmodel.LoginViewModel. [class android.app.Application] 经过一下午的思索&#xff0c;终于找…...

智慧互联,有序充电--多场景充电

企业微电网能效及充电管理解决方案 安科瑞 崔丽洁 1、企业需求&#xff08;目的地充电&#xff09; 站在企业的角度&#xff0c;除了要主动承担碳达峰、碳中和的社会责任&#xff0c;也需要考虑自身的经营和利润&#xff0c;需要结合企业的现状进行改造 企业微电网平台——与…...

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知识点 – 网络基础&#xff08;一&#xff09; 文章目录 Linux知识点 -- 网络基础&#xff08;一&#xff09;一、网络发展二、协议1.OSI七层模型2.TCP/IP五层&#xff08;或四层&#xff09;模型 三、网络传输基本流程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 -…...

美创科技“签”手柠檬文才学堂,共推高校数据安全建设

近日&#xff0c;由柠檬文才学堂联合中国教育在线、东北财经大学网络教育学院共同主办的“三教统筹下高校继续教育数字化转型研讨”顺利召开。 国内高等院校&#xff08;高职院校&#xff09;继续教育分管领导&#xff0c;继续教育学院领导及继续教育信息化、教学教务管理、课程…...

【JAVA基础】数据类型,逻辑控制

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 数据类型整型变量 int长整型变量 long单精度浮点数 float双精度浮点数 double字符类型 char字节…...

计算机竞赛 基于图像识别的跌倒检测算法

前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于图像识别的跌倒检测算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/…...

计算机竞赛 基于大数据的股票量化分析与股价预测系统

文章目录 0 前言1 课题背景2 实现效果3 设计原理QTChartsarma模型预测K-means聚类算法算法实现关键问题说明 4 部分核心代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的股票量化分析与股价预测系统 该项目较为新颖…...

input子系统

内核分三层 1、事件处理层 2、核心层 3、设备驱动层 当硬件按下&#xff0c;在设备驱动中触发中断&#xff0c;中断程序会将事件上报给核心层 核心层将事件给事件处理层&#xff0c;最后事件处理层控制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文件&#xff0c;拷贝到/etc…...

C++ using关键字

C using关键字 using关键字用来简化代码和提高可读性。 using关键字提供了一种灵活的方式&#xff0c;可以在C中导入命名空间和定义别名。 1. 导入命名空间 using namespace 可以将一个命名空间中的所有名称导入到当前作用域中&#xff0c;从而可以直接使用该命名空间中的所…...

让你对es有一个初步的了解

首先es在海量数据的搜索能力非常好&#xff0c;es你可以把他看成一个搜索引擎数据库&#xff0c;他是个非关系型数据库。他的语法有很大的不同&#xff0c;好像都是json风格的。还有一点需要说的就是es 的数据是存在硬盘上的&#xff0c; 我们先来看一下mysql和es的区别吧。一…...

编绎和优化,脚本代码小米加步枪赶超英法美

编程达人&#xff1a;冰冻牡蛎 测试&#xff0c;总结》》 今有空&#xff0c;继续看了一下竹笋大师几天前提出的“使用for循环查找10亿内可被7整除的数的个数”的题目&#xff08;相关文件&#xff1a;群文件 10亿以内多少个数字可以整除7.7z &#xff09; 1. 论输出的exe大小…...

数字电路-二进制学习

什么是二进制&#xff1f; 数字电路 中 只有 高电平 和低电平 就是 1 和0 进位规则是“逢二进一”&#xff0c;借位规则是“借一当二”。 二进制、八进制 、十进制、十六进制 二进制 有两个数来表示 &#xff1a; 0、1 八进制 有8个数来表示 &#xff1a; 0、1、2、3、4、…...

运维Shell脚本小试牛刀(一)

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 一: Shell中循环剖析 for 循环....... #!/bin/bash - # # # # FILE: countloop.sh # USAGE: ./countloop.sh # DESCRIPTION: # OPTIONS: ------- # …...

screen命令,可以断开服务器连接,依旧能运行你的程序了

可以参考博客1&#xff1a;https://blog.csdn.net/nima_zhang_b/article/details/82797928 可以参考博客2:https://blog.csdn.net/herocheney/article/details/130984403 Linux中的screen是一个命令行工具&#xff0c;可以让用户在同一个终端会话中创建多个虚拟终端。它非常有…...

【ArcGIS Pro二次开发】(63):批量更改字段别名

在我工作中遇到的大多数图斑&#xff0c;字段名称一般是英文&#xff0c;字段别名是中文&#xff0c;使用起来是比较方便的。 但有时候也会遇到一些不一样的情况&#xff0c;不知是经过了怎样的处理&#xff0c;图斑的字段别名被修改成了和字段名称一样的英文&#xff0c;这样…...

redis全套参数配置及降级解决方案

文章目录 redis高可用核心参数配置1.Lettuce2.Jedis3.Redisson4.其他客户端 redis降级场景简介一、业务背景二、设计方案三、实现方案四、总结 redis高可用核心参数配置 1.Lettuce 提示&#xff1a;该客户端无主动探活机制&#xff0c;只能依赖于 OS KeepaAlive 机制&#xf…...

AMD即将上市大量中端显卡,为新显卡支付过高价格的日子可能结束

​AMD在本周末&#xff08;8月25日&#xff09;的德国Gamescom活动中展示了两款新显卡和一些新的升级技术&#xff0c;这些新GPU的定价将与英伟达的GeForce RTX 4000卡竞争。 这是一件大事&#xff0c;因为新的Radeon RX 7700 XT和7800 XT卡占据了AMD Radeon RX 7000系列产品线…...

go学习一之go的初体验

go语言学习笔记 一、golang初体验: 1.简单体验案例&#xff1a; package main{ //把这个test.go归属到main import "fmt" //引入一个包 func main(){//输出hellofmt.Println("hello world")} }2.从案例学到的知识点&#xff1a; (1) go文件的后缀是.…...

智能制造产业链数字化转型、数字化互联工厂建设方案PPT

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除&#xff0c;更多浏览公众号&#xff1a;智慧方案文库 篇幅有限&#xff0c;无法完全展示&#xff0c;喜欢资料可转发评论&#xff0c;私信了解更多信息。...

【安卓】拿注册码的两种方式

【安卓】拿注册码的两种方式 文章仅用于学习交流&#xff0c;请勿利用文章中的技术对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xff0c;均由使用者本人负责。首发吾爱&#xff1a;https://www.52pojie.cn/thread-1826802-1-1.html言归…...

【C++】—— 异常处理

前言&#xff1a; 本期&#xff0c;我将给大家讲解的是有关 异常处理 的相关知识&#xff01; 目录 &#xff08;一&#xff09;C语言传统的处理错误的方式 &#xff08;二&#xff09;C异常概念 &#xff08;三&#xff09;异常的使用 1、异常的抛出和捕获 1️⃣ 异常的…...

cookie和session是什么,区别是什么?

cookie HTTP 协议中的 Cookie 包括 Web Cookie 和浏览器 Cookie&#xff0c;它是服务器发送到 Web 浏览器的⼀ ⼩块数据。服务器发送到浏览器的 Cookie&#xff0c;浏览器会进⾏存储&#xff0c;并与下⼀个请求⼀起发送到服务器。通 常&#xff0c;它⽤于判断两个请求是否来⾃…...

linux的mmc子系统与块设备关联

1.前言 本文主要block组件的主要流程&#xff0c;在介绍的过程中&#xff0c;将详细说明和block相关的流程&#xff0c;涉及到其它组件的详细流程再在相关文章中说明。 2.主要数据结构和API 2.1 struct mmc_card Elemete Namestruct mmc_cardPathinclude/linux/mmc/card.hRe…...