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

线程池的讲解和实现

🚀🚀🚀🚀🚀🚀🚀大家好,今天为大家带来线程池相关知识的讲解,并且实现一个线程池

🌸🌸🌸🌸🌸🌸🌸🌸

                                         目录

                                  🌸 1.线程池的定义

                             🌸2.线程池相关类的认识

                         🌸3.线程池的拒绝策略

                       🌸4.线程池的实现

1.线程池的定义

我们可以这样来理解

我们之前创建线程的时候一直都是向系统申请资源,虽然说线程轻量,但是频繁的创建也会消耗资源,开校是不可忽略的.因此,我们就使用线程池,用到线程的时候直接到池子里取,用完之后还给线程池就好,也就是随用随调

那么线程池有什么好处呢?

  1. 降低资源消耗:减少线程的创建和销毁带来的性能开销。
  2. 提高响应速度:当任务来时可以直接使用,不用等待线程创建
  3. 可管理性: 进行统一的分配,监控,避免大量的线程间因互相抢占系统资源导致的阻塞现象

为什么从线程池取线程要比从系统申请效率更高呢

因为从线程池取线程是纯粹的用户态操作

从系统创建线程,涉及到内核态和用户态的切换

说到这里,什么是内核态,什么是用户态台呢,我们来看一看官方的介绍

内核态:当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。其他的属于用户态。用户程序运行在用户态,操作系统运行在内核态.(操作系统内核运行在内核态,而服务器运行在用户态)。用户态不能干扰内核态.所以CPU指令就有两种,特权指令和非特权指令.不同的状态对应不同的指令。

  我们举一个现实中的例子,假如A要去银行办一张银行卡,那么

 场景:银行

滑稽老铁:你好,我想办一张银行卡

柜台人员:先生您好,请出示您的身份证复印件

滑稽老铁:啊,我忘记复印了我只带来身份证咋办

柜台人员:没关系的先生,您可以到大厅的复印机打印一张然后拿过来,或者您也可以给我我给您打印😊

滑稽老铁:哦哦,好的,那我去大厅的复印机打印

于是滑稽老铁很快打印完很快就回来了,并且很快完成了银行卡的办理

这真是一次愉悦的体验


 场景:银行

滑稽老铁:你好,我想办一张银行卡

柜台人员:先生您好,请出示您的身份证复印件

滑稽老铁:啊,我忘记复印了我只带来身份证咋办

柜台人员:没关系的先生,您可以到大厅的复印机打印一张然后拿过来,或者您也可以给我我给您打印😊

滑稽老铁:哦哦,好的,那麻烦你给我打印一下

柜台人员:好的先生,稍等

就这样,过了很久,柜台工作人员回来了,然后给滑稽老铁办好了银行卡

这真的不是愉悦的体验

因为要是让滑稽老铁自己打印,那么滑稽老铁不会墨迹,会飞快的打印完,回来办上银行卡

如果交给工作人员,他可能会先接杯水,再和别人唠会嗑啥的,会很慢

这里的滑稽老铁就是用户态,柜台里的工作人员就是内核态,滑稽老铁去大厅自己打印就是相当于线程池取线程,是纯用户态的操作而将身份证给柜台人员打印相当于向系统申请资源创建线程,涉及到内核态和用户态的切换

2.线程池相关类的知识

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** Created with IntelliJ IDEA.* Description:* User: WHY* Date: 2023-03-25* Time: 13:42*/
public class ThreadDemo1 {public static void main(String[] args) {ExecutorService pool= Executors.newFixedThreadPool(10);pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});pool.shutdown();//线程池的销毁}}

Java标准库实现了线程池

ExcutorService直译为执行服务,也就是线程

在这个代码中我们不是通过new一个 ExcutorService创建持,而是通过调用Excutors类的静态方法来完成构造

我们把不通过构造方法,而是通过普通的静态方法来完成对象创建和构造的过程叫做工厂模式

工厂模式其实就是拿来填构造方法的坑的

当我们算一个坐标的时候,我们可以通过读横纵坐标,也可以通过极坐标的方式

来写一个伪代码

class  Point{

public Point(double x,double y)

}

public  Point(double r,double a){

}

}

我想求该点坐标,有两种方法可以完成,但是这两个方法得构成重载才行,但现在完全不符合

那么我们可以搞两个普通方法实现

public static  Point   getPointByXY(double x,double y){

//在这里new对象 new point()

//设置属性

return 

}

public static Point getPointByRA(double r,double a){

//new 对象

//设置属性

//return

}

Executors 创建线程池的几种方式
newFixedThreadPool: 创建固定线程数的线程池
newCachedThreadPool: 创建线程数目动态增长的线程池.
newSingleThreadExecutor: 创建只包含单个线程的线程池.

线程池的销毁:pool.shutdown()方法

 

上述的工厂类都是对ThreadPoolExecutor 类的封装.

下面我们来说一说ThreadpoolExecutor类

 

    • int corePoolSize:核心线程数
    • int maximumPoolSize:最大线程数=核心线程数+临时线程数
    • long keepAliveTime:临时线程保持存活的时间

      • TimeUnit unit:时间单位  s,分钟,ms
    • BlockingQueue<Runnable> workQueue:线程池要管理很多任务,这些任务放到阻塞队列里

submit方法就是把任务放到池子里

3.线程池的拒绝策略

现在来说一说线程池的拒绝策略(非常非常重要)

 

    • ThreadPoolExecutor.AbortPolicy

      被拒绝的任务的处理程序,抛出一个 RejectedExecutionException

      //也就是说当队列满了,再添加任务,就抛出异常,原来的任务和新增的都不干了

      • ThreadPoolExecutor.CallerRunsPolicy

        一个被拒绝的任务的处理程序,直接在 execute方法的调用线程中运行被拒绝的任务,除非执行程序已经被关闭,否则这个任务被丢弃。

        //拒绝执行新来的任务,让发布这个任务或者调用这个任务的人自己去执行,添加的线程去执行这个任务

        • ThreadPoolExecutor.DiscardOldestPolicy

          被拒绝的任务的处理程序,丢弃最旧的未处理请求,然后重试 execute ,除非执行程序关闭,在这种情况下,任务被丢弃。

          //丢弃最老任务,执行新来的任务,最老任务是指最下安排的任务,也就是阻塞队列的队首元素

          • ThreadPoolExecutor.DiscardPolicy

            被拒绝的任务的处理程序静默地丢弃被拒绝的任务。

            //不执行新的任务,丢弃最新任务

上述的ThreadPoolExecutor类的参数以及四个拒绝策略是重点!!!

4.线程池的实现

说到这里,我们已经基本清楚线程池,下面来自己实现一个线程池

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;/*** Created with IntelliJ IDEA.* Description:* User: WHY* Date: 2023-03-25* Time: 14:46*/
class MyThreadPool{//阻塞队列存放任务private BlockingQueue<Runnable> queue=new LinkedBlockingQueue<>();//将任务放到队列public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}//实现固定线程数的线程池public MyThreadPool(int n){for(int i=0;i<n;i++){Thread t=new Thread(()->{try {while(true) {Runnable runnable = queue.take();runnable.run();}} catch (InterruptedException e) {throw new RuntimeException(e);}});t.start();}}}public class ThreadingDemo2 {public static void main(String[] args) throws InterruptedException {MyThreadPool  pool=new MyThreadPool(10);for(int i=0;i<1000;i++){int number=i;pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello"+number);}});}}
}

这就是线程池今天全部的内容了,我们今天的讲解就到这里

下期再见,886!!!

 

相关文章:

线程池的讲解和实现

&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;大家好,今天为大家带来线程池相关知识的讲解,并且实现一个线程池 &#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;…...

linux编程──gcc和clang

实验链接 编译原理实验-GCC/Clang工具链在ARM架构上的使用 实验报告 第1关&#xff1a;理解程序的不同表示形式 ##问题1-1&#xff1a; 如果在命令行下执行 gcc -DNEG -E sample.c -o sample.i生成的sample.i 与之前的有何区别&#xff1f; 根据定义NEG,而选择了M定义为-4…...

字节跳动测试岗面试记:二面被按地上血虐,所幸Offer已到手...

在互联网做了几年之后&#xff0c;去大厂“镀镀金”是大部分人的首选。大厂不仅待遇高、福利好&#xff0c;更重要的是&#xff0c;它是对你专业能力的背书&#xff0c;大厂工作背景多少会给你的简历增加几分竞争力。 但说实话&#xff0c;想进大厂还真没那么容易。最近面试字…...

5.多线程学习

作者&#xff1a;爱塔居 专栏&#xff1a;JavaEE 作者简介&#xff1a;大三学生&#xff0c;喜欢总结与分享~ 文章目录 目录 文章目录 章节回顾 一、wait 和notify 二、设计模式 2.1 单例模式 章节回顾 线程安全 1.一个线程不安全的案例&#xff08;两个线程各自自增5w次&…...

数据结构中的堆

一、树的重要知识点 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff08;有几个孩子&#xff09;叶节点或终端节点:度为0的节点称为叶节点&#xff1b;如上图&#xff1a;B、C、H、I...等节点为叶节点&#xff08;0个孩子&#xff09;非终端节点或分支节点…...

Linux内核设备信息集合

本文结合设备信息集合的详细讲解来认识一下设备和驱动是如何绑定的。所谓设备信息集合&#xff0c;就是根据不同的外设寻找各自的外设信息&#xff0c;我们知道一个完整的开发板有 CPU 和各种控制器&#xff08;如 I2C 控制器、SPI 控制器、DMA 控制器等&#xff09;&#xff0…...

若依框架---权限管理设计

前言 若依权限管理包含两个部分&#xff1a;菜单权限 和 数据权限。菜单权限控制着我们可以执行哪些操作。数据权限控制着我们可以看到哪些数据。 菜单是一个概括性名称&#xff0c;可以细分为目录、菜单和按钮&#xff0c;以若依自身为例&#xff1a; 目录&#xff0c;就是页…...

Java设计模式(二)——工厂模式

当用户需要一个类的子类实例&#xff0c;且不希望与该类的子类形成耦合或者不知道该类有哪些子类可用时&#xff0c;可采用工厂模式&#xff1b;当用户需要系统提供多个对象&#xff0c;且希望和创建对象的类解耦时&#xff0c;可采用抽象工厂模式。 工厂模式一般分为简单工厂、…...

【Maven】

MavenMaven简介仓库坐标Maven项目构建依赖管理生命周期及插件插件模块拆分与开发聚合继承属性版本管理资源配置多环境开发配置跳过测试私服Maven简介 Maven的本质时一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型(POM) POM(Project Object Model)&a…...

[JAVA]继承

目录 1.继承的概念 2.继承的语法 3.父类成员访问 3.1子类中访问父类成员变量 3.2子类中访问父类成员方法 4.super关键字 5.子类构造方法 6.继承方式 7.final关键字和类的关系 面向对象思想中提出了继承的概念&#xff0c;专门用来进行共性抽取&#xff0c;实现代码复…...

Vue3 pinia持久化存储(组合式Api案例演示)

pinia-plugin-persist&#xff08; pinia持久化插件&#xff09; 本文采用的是 组合式Api的方式来做Pinia的持久化存储演示 如果对pinia的持久化还是不是很了解的&#x1f468;‍&#x1f393;&#xff5c;&#x1f469;‍&#x1f393;&#xff0c;可以看一下笔者的上一篇文章…...

8个你一看就觉得很棒的Vue开发技巧

1.路由参数解耦 通常在组件中使用路由参数&#xff0c;大多数人会做以下事情。 export default {methods: {getParamsId() {return this.$route.params.id}} }在组件中使用 $route 会导致与其相应路由的高度耦合&#xff0c;通过将其限制为某些 URL 来限制组件的灵活性。 正…...

vue3+ts 开发效率提升

1、vite pnpm项目初始化 pnpm&#xff1a; 比npm或yarn快10倍 pnpm与其他包管理器&#xff08;如npm和Yarn&#xff09;的不同之处在于它使用一种称为“硬链接”的独特安装方法。当你使用PNPM安装一个包时&#xff0c;它并不会将包的文件复制到每个项目的node_modules目录中&a…...

【数据结构与算法】队列和栈的相互实现以及循环队列

目录&#x1f314;一.用队列实现栈&#x1f319;1.题目描述&#x1f319;2.思路分析&#x1f319;3.代码实现⛈二.用栈实现队列☔1.题目描述☔2.思路分析☔3.代码实现&#x1f308;三.实现循环队列&#x1f314;一.用队列实现栈 &#x1f319;1.题目描述 我们先看一下题目链接…...

mysql连接不上问题解决

公司新搭内网测试环境&#xff0c;mysql远程登录问题解决 远程登录: 1 修改host, mysql> select user,host,plugin from user; ---------------------------------------------------- | user | host | plugin | ------------------------…...

利用nginx实现动静分离的负载均衡集群实战

前言 大家好&#xff0c;我是沐风晓月&#xff0c;今天我们利用nginx来作为负载&#xff0c;实现两台apache服务器的动静分离集群实战&#xff1b; 本文收录于沐风晓月的专栏《linux基本功-系统服务实战》&#xff0c;更多内容可以关注我的博客&#xff1a; https://blog.csd…...

与chatGPT神聊,引领你深入浅出系统调用

在操作系统的教学中&#xff0c;系统调用的作用不言而喻&#xff0c;但是&#xff0c;对系统调用常常是雾里看花&#xff0c;似乎明白&#xff0c;又难以真正的触及&#xff0c;即使在代码中调用了系统调用&#xff0c;比如调用fork&#xff08;&#xff09;创建进程&#xff0…...

自学大数据第十天~Hbase

随着数据量的增多,数据的类型也不像原来那样都是结构化数据,还有非结构化数据; Hbase时google 的bigtable的开源实现, BigtableHbase文件存储系统GFSHDFS海量数据处理MRMR协同管理服务chubbyzookeeper虽然有了HDFS和MR,但是对于数据的实时处理是比较困难的,没有办法应对数据的…...

vue更高效的工具-vite

目录 1.webpack 2.vite是什么 3.使用vite创建项目 4.最后总结 &#x1f43c;webpack 简单来说&#xff0c;Webpack是一个打包工具。 站在2018年的角度&#xff0c;成为一个优秀的前端工程师&#xff0c;除了要会写页面样式和动态效果之外&#xff0c;还需要会用主流的单页…...

HFish蜜罐的介绍和简单测试(一)

目录 0、什么是蜜罐 0.1、蜜罐的定义 0.2、蜜罐的优势 0.3、蜜罐与情报 1、HFish介绍 1.1、设计理念 1.2、HFish架构 1.3、HFish特点 1.4、常见蜜罐场景 2、快速部署 2.1、环境要求 2.2、联网环境&#xff0c;一键安装 2.3、安装效果 3、错误排查 3.1、管理端问题…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...