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

【Java多线程】对线程池的理解并模拟实现线程池

目录

1、池

 1.1、线程池

2、ThreadPoolExecutor 线程池类

3、Executors 工厂类

4、模拟实现线程池



1、池

“池”这个概念见到非常多,例如常量池、数据库连接池、线程池、进程池、内存池。

所谓“池”的概念就是:(提高效率)
1、提前把要用的对象准备好
2、用完的对象也不立即释放,留着以备下次使用。
从而大大降低了线程频繁地创建销毁造成的开销

 1.1、线程池

线程池也是如此,提前把要使用的线程,在线程池中准备好,等到需要用时就从池子里取

出,用完之后再归还给池子。

(其中取出和归还操作都是属于纯用户态代码,这就比内核操作更快,更可控) 

上面提到了用户态,什么是用户态呢?

        设想一个场景,你在银行柜台办理业务,该业务需要用到身份证复印件,此时有两种选择:一种是柜员拿着你的身份证帮你去复印,一种是你自己去复印。

        显然自己去复印这个操作更加可靠,并且可控一些。如果交给柜员去复印,天知道柜员拿了你的身份证后还去做了什么,因为柜员本身需要处理的事情不止有帮你复印身份证这一件事,可能在帮你复印身份证的路上去做了别的事情,你能做的就只有在柜台前等柜员回来,这种操作显然更加不可控。

你自己去操作就相当于用户态,而柜员帮你操作就相当于是内核态

而类比到计算机上简单来说就是:

如果一个任务,是在用户程序上完成的,就属于用户态,此时更加的可控。

如果一个任务,是通过系统申请创建线程,需要由内核来完成,就属于内核态,此时更加不可控。

2、ThreadPoolExecutor 线程池类

 Java 在标准库中提供了 ThreadPoolExecutor 线程池类

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • keepAliveTime:空闲时保持存活的时间(针对临时线程的)
  • unit:存活时间的时间单位(s,min,ms,hour....)
  • workQueue:阻塞队列,和定时器类似,线程池中也可以持有很多个任务
  • threadFactory:线程工厂(这个类中的方法封装了 new Thread 的操作,同时给 Thread 设置了一些属性)
  • handler拒绝策略,当线程池中的阻塞队列满时,继续往队列中添加任务,此时线程池会执行什么样的操作就称为拒绝策略

针对拒绝策略,又分为四种:

1、继续添加任务直接拒绝接收并报错。【直接报错,新旧任务都不干了】

2、新的任务,由添加任务的线程负责执行。【谁揽的活儿谁干】

3、丢弃最旧的任务,新的添加进来。

4、丢弃新来的任务。

3、Executors 工厂类

ThreadPoolExecutor 本身用起来比较复杂,因此标准库还把 ThreadPoolExecutor 封装了一层,提供了另一个版本。

即 Executors 工厂类,通过这个类来创建出不同的线程池对象。

Executors 创建线程池的几种方式:

  • newFixedThreadPool: 创建固定线程数的线程池
  • newCachedThreadPool: 创建线程数目动态增长的线程池.
  • newSingleThreadExecutor: 创建只包含单个线程的线程池.
  • newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.
public class ExecutorDemo {public static void main(String[] args) {//将线程数设置为 10ExecutorService service = Executors.newFixedThreadPool(10);//使用 submit 方法向线程池中提交任务service.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello Executors");}});}
}

既然 ThreadPoolExecutor 和 Executors 都可以创建线程池,那么到底该用哪个呢?

正常情况下直接使用 Executors 工厂类即可,当 Executors 工厂类提供的方法无法满足使用时,或者是想要高度定制化线程池时,才去使用 ThreadPoolExecutor。

4、模拟实现线程池

这里模拟写一个固定线程数目的线程池,即模拟使用 newFixedThreadPool 创建的线程池。

分析要点:

1、首先需要提供构造方法,方法中指定创建多少个线程

2、在构造方法中,把这些线程都创建好

3、用一个阻塞队列,将要执行的任务保存起来

4、提供 submit 方法,用于添加新的任务到阻塞队列中

public class MyThreadPoolExecutor {// 保存线程的集合private List<Thread> threadList = new ArrayList<>();// 保存任务的阻塞队列private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);public MyThreadPoolExecutor(int n) {  //创建n个线程for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {//这些线程需要做的就是不断从任务队列中取出任务并执行while (true) {try {// take 带有阻塞功能,为空时自动阻塞Runnable runnable = queue.take();runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});//启动线程t.start();//将线程存入集合中,以备后续使用threadList.add(t);}}//submit 添加新的任务到队列中public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}
}

【博主推荐】 

【Java多线程】线程中几个常见的属性以及状态-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136122127?spm=1001.2014.3001.5501【Java多线程】Thread类的基本用法-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136121421?spm=1001.2014.3001.5501【Java多线程】对进程与线程的理解-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/136115808?spm=1001.2014.3001.5501

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

相关文章:

【Java多线程】对线程池的理解并模拟实现线程池

目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多&#xff0c;例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是&#xff1a;&#xff08;提高效率&#xff09; 1…...

python连接mysql数据库

连接MySQL数据库&#xff0c;通常我们会使用Python的mysql-connector-python库。下面是一个基本的示例来展示如何使用Python连接到MySQL数据库。 首先&#xff0c;确保你已经安装了mysql-connector-python库。如果没有&#xff0c;你可以使用pip来安装它&#xff1a; pip ins…...

docker用法

首先需要去docker官网注册你的账号&#xff0c;记住账号名称和密码&#xff1b; 然后在本地执行&#xff1a; docker login登录OK。 把ubuntu下载到本地&#xff1a; sudo docker pull ubuntusudo docker images输出&#xff1a; REPOSITORY TAG …...

DIcom调试Planar configuration

最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容&#xff0c;自己写得原生解析不兼容。 给对方调好了格式&#xff0c;下次生成文件还会有错。 简单记录下&#xff0c;日后备查。 今天对方又加了 个字段&#xff1a;Planar configuration 查…...

C#与VisionPro联合开发——跳转页面

1、跳转页面并打开相机 From1 所有代码展示 using System; using System.IO; using System.Windows.Forms; //引入VisionPro命名空间 using Cognex.VisionPro;namespace ConnectCamera {public partial class Form1 : Form {public Form1() {InitializeComponent();}CogAcqFif…...

服务端测试开发必备技能:Mock测试

什么是mock测试 Mock 测试就是在测试活动中&#xff0c;对于某些不容易构造或者不容易获取的数据/场景&#xff0c;用一个Mock对象来创建以便测试的测试方法。 Mock测试常见场景 无法控制第三方系统接口的返回&#xff0c;返回的数据不满足要求依赖的接口还未开发完成&#…...

vue3中ref创建变量取值时自动补充 .value 插件 volar

插件 TypeScript Vue Plugin (Volar) 设置中配置...

clickhouse的docker部署与springboot整合

注意:镜像bitnami/clickhouse包含服务端和客户端,yandex版本需要使用yandex/clickhouse-server,yandex/clickhouse-server docker启动命令(允许空密码 -e ALLOW_EMPTY_PASSWORD=yes),clickhouse版本不同,配置文件在的位置也会不一样/etc/clickhouse-server/config.xml d…...

Node.js_基础知识(计算机硬件基础)

主机的基本组成 CPU:Central Processing Unit,即中央处理器,是计算机的核心部件。是一块集成电路芯片,能够执行计算机指令并控制计算机的各种操作,负责运算和处理数据内存:是电脑硬件中的一块电路板,用于暂时存储CPU中的运算数据,是计算机与CPU进行沟通的桥梁,负责存储…...

git bash :download.sh: line 1: wget: command not found(已解决)

Windows中git bash完全可以替代原生的cmd&#xff0c;但是对于git bash会有一些Linux下广泛使用的命令的缺失&#xff0c;比如wget命令。 1、下载wget.exe&#xff0c;地址&#xff1a;https://eternallybored.org/misc/wget/ 2、将wget.exe 拷贝到C:\Program Files\Git\ming…...

BlackberryQ10 是可以安装 Android 4.3 应用的,Web UserAgent 版本信息

BlackberryQ10 是可以安装 Android 4.3 应用的 最近淘了个 Q10 手机&#xff0c;非常稀罕它&#xff0c;拿着手感一流。这么好的东西&#xff0c;就想给它装点东西&#xff0c;但目前所有的应用都已经抛弃这个安卓版本了。 一、开发环境介绍 BlackBerry Q10 的 安卓版本是 4.…...

JS前端高频面试

JS数据类型有哪些&#xff0c;区别是什么 js数据类型分为原始数据类型和引用数据类型。 原始数据类型包括&#xff1a;number&#xff0c;string&#xff0c;boolean&#xff0c;null&#xff0c;undefined&#xff0c;和es6新增的两种类型&#xff1a;bigint 和 symbol。&am…...

Flask数据库操作-Flask-SQLAlchemy

Flask中一般使用flask-sqlalchemy来操作数据库。flask-sqlalchemy的使用介绍如下&#xff1a; 一、SQLAlchemy SQLALchemy 实际上是对数据库的抽象&#xff0c;让开发者不用直接和 SQL 语句打交道&#xff0c;而是通过 Python 对象来操作数据库&#xff0c;在舍弃一些性能开销…...

H5获取手机相机或相册图片两种方式-Android通过webview传递多张照片给H5

需求目的&#xff1a; 手机机通过webView展示H5网页&#xff0c;在特殊场景下&#xff0c;需要使用相机拍照或者从相册获取照片&#xff0c;上传后台。 完整流程效果&#xff1a; 如下图 一、H5界面样例代码 使用html文件格式&#xff0c;文件直接打开就可以展示布局&#…...

mysql进阶学习 | DAY 14

存储引擎 体系结构 连接层 服务层 引擎层 存储层 存储引擎 表类型 查看引擎 查看建表语句 指定存储引擎 ENGINE SHOW engins InnoDB 默认存储引擎 遵循ACID模型 支持事务 行级锁 提高并发访问性能 支持外键 FOREIGN KEY约束 保证数据完整性和正确性 对应文件 xx…...

使用GPT生成python图表

首先&#xff0c;生成一脚本&#xff0c;读取到所需的excel表格 import xlrddata xlrd.open_workbook(xxxx.xls) # 打开xls文件 table data.sheet_by_index(0) # 通过索引获取表格# 初始化奖项字典 awards_dict {"一等奖": 0,"二等奖": 0,"三等…...

[深度学习]yolov9+deepsort+pyqt5实现目标追踪

【YOLOv9DeepSORTPyQt5追踪介绍】 随着人工智能技术的飞速发展&#xff0c;目标追踪在视频监控、自动驾驶等领域的应用日益广泛。其中&#xff0c;YOLOv9作为先进的目标检测算法&#xff0c;结合DeepSORT多目标追踪算法和PyQt5图形界面库&#xff0c;能够为用户提供高效、直观…...

C#_WaitAll、WhenAll、async及await

Task.WhenAll、Task.WaitAll Task.WhenAll 和 Task.WaitAll 都是用于等待多个任务完成的方法&#xff0c;但它们之间有一些重要的区别。 返回类型: Task.WhenAll: 返回一个 Task 对象&#xff0c;该对象表示所有输入任务的联合任务。 Task.WaitAll: 没有返回值。它是一个同步方…...

leetcode hot100零钱兑换Ⅱ

本题可以看出也是背包问题&#xff0c;但区别于之前的01背包问题&#xff0c;这个是完全背包问题的变形形式。 下面介绍01背包和完全背包的区别与联系&#xff1a; 01背包是背包中的物品只能用一次&#xff0c;不可以重复使用&#xff0c;而完全背包则是可以重复使用。01/完全…...

路由器配置DMZ主机映射

路由器配置DMZ主机映射 光猫路由模式配置方法 光猫路由模式是用光猫进行拨号连接&#xff0c;所有设备通过光猫访问互联网&#xff0c;只需要设置光猫的DMZ主机映射地址为局域网主机即可 光猫桥接模式配置方法 光猫桥接模式&#xff0c;是穿透光猫&#xff0c;通过路由器拨…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...