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

长沙做网站的公司/软文营销案例文章

长沙做网站的公司,软文营销案例文章,湖北省招投标交易云平台,沙井网站开发目录 1. 线程正常的生命周期 2. 为什么要用线程池? 3. 线程池的核心原理 4. 怎样创建线程池? 5.线程池的代码实现 6. ThreadPoolExecutor 源码分析 7. ThreadPoolExecutor 工作原理展示(重点) 1. 线程正常的生命周期 我们知…

目录

1. 线程正常的生命周期

2. 为什么要用线程池?

3. 线程池的核心原理

4. 怎样创建线程池?

5.线程池的代码实现

6. ThreadPoolExecutor 源码分析

7. ThreadPoolExecutor 工作原理展示(重点)


1. 线程正常的生命周期

我们知道,线程是有生命周期的,在中间不出现阻塞情况下,线程从一开始的新建状态——>就绪状态——>运行状态——>死亡状态。

2. 为什么要用线程池?

在我们实际开发业务需求时,往往会有很多的用户访问我们的业务,如果来一个用户就创建一个线程,用户结束又销毁线程,如此频繁往复,是非常消耗系统的性能的,因此在实际开发业务时,我们往往会使用线程池。

线程池的好处就是,我们可以在线程池中创建多个线程,当我们有业务需要用到线程时,它会自动到线程池中拿取已经存在线程而不会再去创建新的线程,当线程完成了相应业务后,它会把使用过的线程再还到线程池中而不会销毁它,等待下一次任务的执行,如此一来,就节省了线程的创建与销毁这一动作,提高了程序的运行效率。

3. 线程池的核心原理

(1)我们在初始创建线程池的时候,线程池是空的,当然我们也可以在创建线程池的时候就定义好线程池中有几个线程。

(2)当我们需要用到线程时,线程池会去创建新的线程对象,当任务执行完毕之后,它会把线程归还给线程池,下次再有业务需要用到线程时,不会去创建新的线程,直接复用线程池中已经存在的线程。

(3)如果有多个任务都需要使用线程,但是线程池中的线程都正在工作时,而且也无法在创建多余的线程,那么当钱的任务就会进行等待,什么时候有空余线程,任务就会再次开启。

4. 怎样创建线程池?

Java已经帮我们封装好了一个关于线程池的工具类,名叫 Executors,我们可以根据这个工具类去创建不同类型的线程池。这里我把 Executors 的源码中所有创建线程池的方式列举下来如下图

这些以 new 开头的都是线程池的构造方法,我们可以用它创建线程池。此外,线程池的类型也有很多种,但底层逻辑都差不多。这里我就随便拿两个当例子说一下。

(1)public static ExecutorsService newCachedThreadPool() ,可以创建一个没有线程上限的线程池,从严格意义上来说,它并不算是没有上限,它的上限就是 int 类型的上限,大约是21亿多,我们看它的源码即可得知,这里它的上显示 Integer 的最大值,但我们肯定不会去创建这么多的线程,服务器也承受不住的。另外先记住,该构造方法底层 new 了一个ThreadPoolExecutor,后面会说到。

public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}

(2)public static ExecutorsService newFixedThreadPool(int nThreads),可以创建一个有上限的线程池,上限就是我们传入的参数。

源码如下所示,这里也先记住,该构造方法 new 了一个ThreadPoolExecutor,后面会说到。

public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}

5.线程池的代码实现

测试线程池如何使用,我们先来定义一个线程类

// 实现 Runnable 接口
public class MyRunnable implements Runnable{// 重写 run 方法,循环5次@Overridepublic void run() {for (int i = 0; i < 5; i++) {
// 获取当前线程名称并打印System.out.println(Thread.currentThread().getName() + "------" + i);}}
}

然后再定义一个线程池,给它多添加几个任务

public static void main(String[] args) {// 创建一个有上限的线程池,上线设置为3ExecutorService pool = Executors.newFixedThreadPool(3);// 给线程池添加任务,多添加几个,超出它的上线
// 任务1pool.submit(new MyRunnable());
// 任务2pool.submit(new MyRunnable());
// 任务3pool.submit(new MyRunnable());
// 任务4pool.submit(new MyRunnable());
// 任务5pool.submit(new MyRunnable());
// 任务6pool.submit(new MyRunnable());}

运行 main 方法,得到如下结果

可以看到,在控制台中,尽管我们定义了6个线程任务,但线程池中却只有3个线程,分别是pool-1-thread-1,pool-1-thread-2,pool-1-thread-3,这也对应了我们创建线程池时标注的最大线程数量3,而且各位也可以发现,pool-1-thread-2 这个线程打印了两次for循环,其实下面还有线程pool-1-thread-1与线程pool-1-thread-3打印的另外两次for循环,从从我们也可以看出来,虽然我们定义了6个线程任务,但我们定义了一个线程池数量最大为3的线程池,当任务开始时,最先来的三个任务会直接使用线程池中的线程,当第四个第五个第六个任务来到时,它会在线程池的外边排队等待,当前三个任务有人把任务做完将线程归还给线程池后,其他排队等待的线程就可以取出线程池去空余的线程去完成自己的任务了!!!

6. ThreadPoolExecutor 源码分析

刚才我们举得那两个例子,特别用加粗字体说明了这两个线程池底层都是 new 了一个ThreadPoolExecutor,下面我们就来看一下它的源码。

在源码中,有好几个ThreadPoolExecutor 的构造方法,其中有一个最重要的,如下所示,该方法中一共有7个参数,我把它们代表的意义都列举出来。

对于 ThreadPoolExecutor 线程池来讲,我们重点需要理解的有两点,第一点就是这一大堆参数各自代表的含义,第二就是线程池的工作原理

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.acc = System.getSecurityManager() == null ?null :AccessController.getContext();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}

int corePoolSize:代表线程池中的核心线程数量;

int maximumPoolSize:代表线程池中最大线程数量;

这里我先解释一下,该线程池中,核心线程永远不会被销毁,除非将线程池销毁,除了核心线程,我们还会有临时线程,就好比是临时工,如果我们线程池的任务过多,核心线程已经忙不过来了,就会有临时线程过来帮忙,当临时线程空闲了一段时间之后没有接到任务,它就又会被销毁。

临时线程 = 最大线程数量 - 核心线程数量

long keepAliveTime:临时线程允许存活的时间数值,如60,100,2000等任意long类型的数都可以;

TimeUnit unit:这个参数与上一个是紧密联系的,代表的是单位,可以为秒,分钟,小时;

如果上面 keepAliveTime 参数数值为60,TimeUnit 单位为Second,则表示表示空余线程可以空闲存活60秒;如果TimeUnit 单位为Minutes,则表示表示空余线程可以空闲存活60分钟,否则就会被销毁。

BlockingQueue<Runnable> workQueue:代表阻塞队列,如果我们的核心线程都在工作时,结果还有任务过来,就会暂时进入到这个阻塞队列中去,可以定义该队列的大小;

ThreadFactory threadFactory:表示我们定义的线程是从哪来的,即创建线程的方式;

RejectedExecutionHandler handler:表示当等待队列满了,临时线程也在工作状态的时候该如何处理,我们可以抛出异常,也可以拒绝服务等等一系列措施。

7. ThreadPoolExecutor 工作原理展示(重点)

刚才我大致说明了 ThreadPoolExecutor 的几个参数代表的意思,下面我来举个例子让大家更好的去理解它

如下所示

现在我定义一个线程池,核心线程数量定义为3,临时线程数量也定义为3,等待队列长度也定义为3,当我们来了10个任务需要线程池去完成时,我来一步步说明,前提是第十个任务来了第一个任务还没有完成,这里我简单描述,各位应该能看懂

(1)第一步,当来了前三个任务,而且是首次接受到任务时,线程池会去创建三个核心线程去处理任务123,如下图所示

(2)第二步,当来了任务456时,因为核心线程都处在工作状态,此时线程456 就会进入到等待队列(也叫阻塞队列)中去排队等待,而不是由临时线程去处理它们;如下图所示

(3)第三步,当来了任务789时,因为此时已经没有空余线程了,等待队列又是满的,此时线程池就会再去创建三个临时线程去处理这任务789;如下图所示

(4)第四步:当提交了第十个任务时,大家可以看到,此时核心线程在工作中,临时线程也在工作中,等待队列也满了,那么此时线程池就会触发拒绝策略;

(5)新来的任务就会被线程池拒绝服务,Java中一共有四种拒绝策略供我们选择,我们可以自行设置,如果不设置默认就是直接将新来的任务丢弃并抛出异常。

此外有一点需要注意,这四种任务拒绝策略都是静态内部类,我们直接通过类名.方法名调用即可。 一般情况下我们也不会去更改拒绝策略,所以其他三种各位同学可以作为了解哦!

相关文章:

线程池工作原理深入解析

目录 1. 线程正常的生命周期 2. 为什么要用线程池&#xff1f; 3. 线程池的核心原理 4. 怎样创建线程池&#xff1f; 5.线程池的代码实现 6. ThreadPoolExecutor 源码分析 7. ThreadPoolExecutor 工作原理展示&#xff08;重点&#xff09; 1. 线程正常的生命周期 我们知…...

chatGPT小白快速入门课程大纲

以下是关于ChatGPT的培训课程大纲,分为7部分,我们会在后续写一个系列的相关文章: 1. 介绍 ChatGPT是什么?ChatGPT是由谁开发的?ChatGPT是一个什么样的语言模型? 2. 功能与特点 ChatGPT可以做什么?ChatGPT有哪些特点?ChatGPT与传统语言模型的区别? 3. 使用方法 如何…...

网络编程——多路复用——epoll机制

理解 epoll&#xff1a;高效的 Linux I/O 多路复用机制 在网络编程中&#xff0c;处理多个并发连接是一个常见的挑战。传统的方式通常使用阻塞式 I/O 或者多线程/多进程来处理并发连接&#xff0c;但这些方法都存在一些性能和资源管理的问题。为了解决这些问题&#xff0c;Lin…...

chapter14:springboot与安全

Spring Boot与安全视频 Spring Security, shiro等安全框架。主要功能是”认证“和”授权“&#xff0c;或者说是访问控制。 认证&#xff08;Authentication&#xff09;是建立在一个声明主体的过程&#xff08;一个主体一般指用户&#xff0c;设备或一些可以在你的应用程序中…...

Linux初识网络基础

目录 网络发展 认识“协议 ” 网络协议 OSI七层模型&#xff1a; TCP/IP五层&#xff08;或四层&#xff09;模型 网络传输基本流程 网络传输流程图&#xff1a; 数据包封装和封用 网络中的地址 认识IP地址&#xff1a; 认识MAC地址&#xff1a; 网络发展 1.独立…...

vue3+ts 动态导入多文件组件

1、在components文件夹中新建index.ts文件&#xff08;components文件夹下为创建的组件&#xff09; // index.ts const modules import.meta.globEager("./*.vue"); //参数为组件路径 let componentsOpts {}const getCaption (obj, str, z: boolean) > {let…...

补充122836356

ul {margin-bottom: 20px;& > li {margin-bottom: 0;} }等效于ul {margin-bottom: 20px; }ul > li {margin-bottom: 0; }CSS中的&代表的什么 如源码&#xff1a; ul{ margin-bottom: 20px; & >li { margin-bottom: 0; } } & 表示嵌套的上一级 这是s…...

记录 pl-table 表格头部文字抖动的问题

本文记录一个实际开发中 pl-table 的问题&#xff0c;项目比较老&#xff0c;vue还是2.x版本。pl-table 是基于 el-table 改造过来的表格展示组件&#xff0c;已经停止更新。 问题描述 当 data 内数据动态改变时&#xff0c;pl-table 的表头部分&#xff0c;列的文字会左右抖动…...

Vite 创建 Vue项目之后,eslint 错误提示的处理

使用 npm create vuelatest创建 vue 项目&#xff08;TS&#xff09;之后&#xff0c;出现了一些 eslint 错误提示&#xff0c;显然&#xff0c;不是代码真实的错误&#xff0c;而是提示搞错了。 vuejs/create-vue: &#x1f6e0;️ The recommended way to start a Vite-pow…...

FFmpeg 硬编码VideoToolBox流程

介绍 FFmpeg已经提供对 VideoToolBox 的编解码支持&#xff1b;主要涉及到的文件有videotoolbox.c、videotoolbox.h、videotoolboxenc.c、ffmepg_videotoolbox.c。在编译 FFmpeg 源码时&#xff0c;想要支持VideoToolBox&#xff0c;在 configure 时&#xff0c;需要–enable-…...

恒盛策略:内盘是买入还是卖出?

内盘&#xff0c;又称成交明细&#xff0c;是指交易所实时发布的每一笔成交价格、交易时刻、成交量等具体数据。关于股民来说&#xff0c;每天重视内盘数据已成为必修课。可是&#xff0c;当看到内盘数据时&#xff0c;很多人都会困惑&#xff0c;到底内盘是买入还是卖出呢&…...

安装Lombok--Lombok的常用注解说明及使用方法

&#x1f600;前言 本篇博文是关于Lombok的基本介绍和基本使用&#xff0c;希望能够帮助到您&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满…...

无涯教程-Perl - endpwent函数

描述 此功能告诉系统您不再希望使用getpwent从密码文件读取条目。在Windows下,使用Win32API::Net函数从域服务器获取信息。 语法 以下是此函数的简单语法- endpwent返回值 此函数不返回任何值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perlwhile(($name, $pas…...

vue项目在body设置公共的背景前提下,区分首页背景图和其他页面背景图

1.需求:在vue项目已设置统一的body背景图的前提,单独给首页换一个背景图,然后其他页面背景图不变的临时需求 实现思路1:在首页home.vue中 在公共的style.css文件中写上两个背景样式(写在公共样式中是因为style.css比组件内部的先加载,避免页面出现后背景空白的问题) …...

测试人员该怎样写软件缺陷报告?

软件测试过程中&#xff0c;每个公司都制订了软件的缺陷处理流程&#xff0c;每个公司的软件缺陷处理流程不尽相同&#xff0c;但是它们遵循的最基本流程是一样的&#xff0c;都要经过提交、分配、确认、处理、复测、关闭等环节&#xff0c;如图1所示。 缺陷处理流程 关于图1所…...

【大数据】Flink 详解(二):核心篇 Ⅱ

Flink 详解&#xff08;二&#xff09;&#xff1a;核心篇 Ⅱ 22、刚才提到 State&#xff0c;那你简单说一下什么是 State。 在 Flink 中&#xff0c;状态 被称作 state&#xff0c;是用来保存中间的计算结果或者缓存数据。根据状态是否需要保存中间结果&#xff0c;分为 无状…...

一孩半政策

一&#xff09; 一孩半&#xff0c;又称独女户二胎&#xff0c;即中国大陆部分农村的一项计划生育政策&#xff0c;第一胎是女孩的夫妻可生育第二个子女。试问这个政策会不会影响男女平衡。 二&#xff09;如果生女孩一直生&#xff0c;直到生男孩停止&#xff0c;试问会不会…...

如何在 Spring Boot 中集成日志框架 SLF4J、Log4j

文章目录 具体步骤附录 笔者的操作环境&#xff1a; Spring Cloud Alibaba&#xff1a;2022.0.0.0-RC2 Spring Cloud&#xff1a;2022.0.0 Spring Boot&#xff1a;3.0.2 Nacos 2.2.3 Maven 3.8.3 JDK 17.0.7 IntelliJ IDEA 2022.3.1 (Ultimate Edition) 具体步骤 因为 …...

如何在Linux布置nginx(附带Nginx基本操作步骤)

文章目录 前言一、下载环境依赖二、下载nginx安装包三、具体操作流程总结 前言 提示&#xff1a;下述操作步骤适合内网服务器、局域网服务器和公网服务器。 不足之处欢迎交流指正&#xff0c;不喜勿喷。 一、下载环境依赖 yum -y install gcc zlib zlib-devel pcre-devel ope…...

Xcode升级导致关联库报错

想办法找到对应的库 然后到 Build Phases -- LinkBinary With Libraries中点击&#xff0c;选择对应的framework即可&#xff0c;就像我工程的报错 Undefined symbol: _OBJC_CLASS_$_ADClient _OBJC_CLASS_$_ASIdentifierManager 缺失的库是AdSupport.framework 添加后再次编…...

利用docker run --rm 命令实现使用宿主机中没有的命令

利用docker run --rm 命令实现使用宿主机中没有的命令 使用容器中的jar命令解压jar包&#xff0c;并将解压内容输出到挂载在宿主机中的目录里使用宿主机中没有的nmap命令来通过端口找IP 使用容器中的jar命令解压jar包&#xff0c;并将解压内容输出到挂载在宿主机中的目录里 do…...

中级课程——XSS

文章目录 介绍挖掘思路分类反射型存储型dom类型 介绍 挖掘思路 注入点&#xff1a;各种输入框 测试代码&#xff08;poc&#xff09;&#xff1a;js语句 分类 反射型 存储型 dom类型...

win10+Vmware+ubuntu18 mosquitto调试记录

记录一下在建立mqtt调试环境上遇到的问题及对策。 我的PC环境为&#xff0c;win10为办公环境&#xff0c;Vmware虚拟机安装ubuntu18&#xff0c;虚拟机主要用来进行代码编译&#xff0c;建立mosquitto server测试环境。 1. ubuntu 安装mosquitto 安装mosquitto网上很多教程&…...

Java EE 突击 9 - Spring Boot 日志文件

Spring Boot 日志文件 学习目标一 . 日志有什么用1.1 日志格式说明 二 . 自定义日志打印2.1 得到日志对象2.2 使用日志对象提供的方法 , 输出自定义的日志内容2.3 日志的级别 三 . 日志持久化3.1 在配置文件里面设置日志名称3.2 设置日志的保存目录 四 . 日志级别的设置五 . 简…...

篇十六:命令模式:封装请求

篇十六&#xff1a;"命令模式&#xff1a;封装请求" 开始本篇文章之前先推荐一个好用的学习工具&#xff0c;AIRIght&#xff0c;借助于AI助手工具&#xff0c;学习事半功倍。欢迎访问&#xff1a;http://airight.fun/。 另外有2本不错的关于设计模式的资料&#x…...

Android 系统框架

启动流程 init 进程启动过程 Android系统启动流程 Zygote启动流程及源码分析 APP启动流程 init进程是Android用户空间第一个进程&#xff0c;主要做以下3件事情&#xff1a; 创建和挂载启动所需的文件目录。初始化和启动关键服务&#xff0c;守护关键服务。解析init.rc配…...

【Hystrix技术指南】(3)超时机制的原理和实现

[每日一句] 也许你度过了很糟糕的一天&#xff0c;但这并不代表你会因此度过糟糕的一生。 [背景介绍] 分布式系统的规模和复杂度不断增加&#xff0c;随着而来的是对分布式系统可用性的要求越来越高。在各种高可用设计模式中&#xff0c;【熔断、隔离、降级、限流】是经常被使…...

MySQL: Failed to Connect to MySQL at XXXX:3306 with user root

客户端连接MySQL服务器&#xff0c;报错&#xff1a; 解决方案&#xff1a; 没有让root用户远程登录&#xff0c;需要设置&#xff1b; 进入MySQL服务器&#xff0c;修改一下 # mysql -h localhost -uroot -P3306 -p12345678 mysql: [Warning] Using a password on the comm…...

《大型网站技术架构设计》第二篇 架构-性能

不同视角下的网站性能 1、用户 从用户角度&#xff0c;网站性能就是用户在浏览器上直观感受到的网站响应速度快还是慢。用户感受到的时间。 2、开发人员 开发人员关注的主要是应用程序本身及其相关子系统的性能&#xff0c;包括响应延迟、系统吞吐量、并发处理能力、系统稳定…...

谷歌推出AI模型机器人RT2 将文本和图像输出为机器人动作

去年年底&#xff0c;ChatGPT火遍全球&#xff0c;全世界都见识了大语言模型的强大力量。人们对大模型不再陌生&#xff0c;开始使用基于大模型的应用绘画、作图、搜索资料、设计剧情等&#xff0c;而妙用不止于此。谷歌推出了Robotics Transformer 2(RT2)&#xff0c;这是一个…...