多线程应用——线程池

线程池

文章目录

  • 线程池
    • 1.什么是线程池
    • 2.为什么要用线程池
    • 3.怎么使用线程池
    • 4.工厂模式
    • 5.自己实现一个线程池
    • 6.创建系统自带的线程池
      • 6.1 拒绝策略
      • 6.2 线程池的工作流程

1.什么是线程池

字面意思,一次创建多个线程,放在一个池子(集合类),用的时候拿一个,用完了之后就放回这个池子就可以了。

2.为什么要用线程池

  1. 首先使用多线程编程就是为了提高效率,势必会创建很多线程,创建的过程是JVM通过调用系统API来申请系统的过程,虽然说创建线程的开销要比创建进程的开销要小的多,但是也架不住特别频繁的创建和销毁,而池化技术就可以减少线程的频繁创建与销毁,从而提高程序性能
  2. JVM调用系统API就意味着从用户态到内核态去执行,而一个系统只有一个内核态,这个内核需要处理很多的事情,所有的进程都是要兼顾到的

因此使用线程池的最主要的目的是为了提高效率,尽量减少从用户态到内核态的切换

3.怎么使用线程池

JDK中提供了一组不同的线程池的实例

public class Demo01 {public static void main(String[] args) {// 1. 用来处理大量短时间工作任务的线程池,如果池中没有可用的线程将创建新的线程,如果线程空闲60秒将收回并移出缓存ExecutorService cachedThreadPool = Executors.newCachedThreadPool();// 2. 创建一个操作无界队列且固定大小线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);// 3. 创建一个操作无界队列且只有一个工作线程的线程池ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();// 4. 创建一个单线程执行器,可以在给定时间后执行或定期执行。ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();// 5. 创建一个指定大小的线程池,可以在给定时间后执行或定期执行。ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);// 6. 创建一个指定大小(不传入参数,为当前机器CPU核心数)的线程池,并行地处理任务,不保证处理顺序Executors.newWorkStealingPool();}
}

以上方法都是用来获取线程池对象的,通过不同的工厂方法获取不同功能的线程池。

4.工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

为什么要使用工厂模式

这里我们用一个简单的例子来说明原因

public class Factory {public static void main(String[] args) {Student student = Student.createByAgeAndName(20, "张三");System.out.println(student);}
}
class Student{private int id;private int age;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Student() {}public Student(int id, String name) { this.id = id;this.name = name;}public Student(int age, String name) {this.age = age;this.name = name;}}

观察上述代码,观察一下有什么问题,当我们想通过id或者age来创建一个学生类时,利用构造方法来创建时,出现了'Student(int, String)' is already defined in... 这里的语法不符合Java语法中重载的语法规则,因此我们使用工厂模式可以解决这类问题。

public class Factory {}
class Student{private int id;private int age;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Student() {}// 通过方法名的区分来分别实现不同的创建对象的方法public static Student createByIdAndName(int id,String name){Student student=new Student();student.setId(id);student.setName(name);return student;}public static Student createByAgeAndName(int age,String name){Student student=new Student();student.setAge(age);student.setName(name);return student;}}

对于工厂模式可以参考以下教程 工厂模式

5.自己实现一个线程池

实现步骤:

  1. 管理任务的一个队列,可以用阻塞队列去实现,使用阻塞队列的好处是,当线程去取任务时,如果队列为空那么就阻塞等待,不会造成过多的CPU资源消耗
  2. 提供一个往队列中添加任务的方法
  3. 创建多个线程,扫描这个队列,如果有任务就拿出来执行
public class MyThreadPool{//定义一个阻塞队列来管理任务BlockingQueue<Runnable>queue=new LinkedBlockingQueue<>();/*** 提供一个往队列中添加任务的方法* @param runnable* @throws InterruptedException*/public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}/*** 提供一个指定了创建线程数的构造方法* @param num*/public MyThreadPool(int num){if(num<=0){throw new RuntimeException("线程数必须大于0");}// 创建线程for (int i = 0; i < num; i++) {Thread thread = new Thread(() -> {while (true){try {Runnable runnable=queue.take();runnable.run();} catch (InterruptedException e) {e.printStackTrace();}}});//启动线程thread.start();}}
}

6.创建系统自带的线程池

在开发过程中一般使用ThreadPoolExecutor这个类来创建线程池,以下为每个参数的代表意义

pool

代码实现

public class Demo {public static void main(String[] args) {ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,//核心线程数10,//最大线程数1,//临时线程的存活时间TimeUnit.SECONDS,//临时线程的存活时间单位new LinkedBlockingQueue<>(20),//阻塞队列的类型和大小);for (int i = 0; i < 100; i++) {int taskId=i;threadPoolExecutor.submit(()->{System.out.println("执行任务 " +taskId+",当前线程:"+Thread.currentThread().getName());});}}
}

6.1 拒绝策略

image-20230906175334118

6.2 线程池的工作流程

image-20230906175032534
关于线程池的分享就到这里了,看完留下的你们的三连吧,你们的支持是我最大的动力!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何将枯燥的大数据进行可视化处理?

在数字时代&#xff0c;大数据已经成为商业、科学、政府和日常生活中不可或缺的一部分。然而&#xff0c;大数据本身往往是枯燥的、难以理解的数字和文字&#xff0c;如果没有有效的方式将其可视化&#xff0c;就会错失其中的宝贵信息。以下是一些方法&#xff0c;可以将枯燥的…

BRAM/URAM资源介绍

BRAM/URAM资源简介 Bram和URAM都是FPGA&#xff08;现场可编程门阵列&#xff09;中的RAM资源。 Bram是Block RAM的缩写&#xff0c;是Xilinx FPGA中常见的RAM资源之一&#xff0c;也是最常用的资源之一。它是一种单独的RAM模块&#xff0c;通常用于存储大量的数据&#xff0…

xctf攻防世界 MISC之CatFlag

0x01.进入环境&#xff0c;下载附件 拿到的是一个无后缀的flag文件&#xff0c;用winhex打开后发现是奇奇怪怪的乱码&#xff0c;用kali的strings搜索也没找到flag情况。 0x02.问题分析 题目提示如图&#xff1a; 让直接cat就行&#xff0c;在kali中直接尝试输入&#xff1a…

springWeb

springweb就是spring框架中的一个模块&#xff0c;对web层进行了封装&#xff0c;使用起来更加方便。如何方便&#xff1f;参数接收框架进行封装 SpringWeb拥有控制器&#xff0c;接收外部请求&#xff0c;解析参数传给服务层。 SpringWeb运行流程 用户发起请求 ip:端口/项目名…

仿射密码 affine

参考链接&#xff1a;https://www.cnblogs.com/0yst3r-2046/p/12172757.html 仿射加密法 在仿射加密法中&#xff0c;字母表的字母被赋予一个数字&#xff0c;例如 a0&#xff0c;b1&#xff0c;c2…z25 。仿射加密法的密钥为0-25直接的数字对。 仿射加密法与单码加密法没什么…

nginx-QPS限制

漏桶算法&#xff1a; 通过nginx配置实现QPS限速。 #设置请求并发量 qps1&#xff0c;不设置burst&#xff0c;会同时处理并发的请求&#xff0c;但是由于我们只设置了1个qps&#xff0c;所以同一时间内的请求&#xff0c;只有一个是正常的&#xff0c;其他都是失败的。 http配…

GRU门控循环单元

GRU 视频链接 https://www.bilibili.com/video/BV1Pk4y177Xg?p23&spm_id_frompageDriver&vd_source3b42b36e44d271f58e90f86679d77db7Zt—更新门 Rt—重置门 控制保存之前一层信息多&#xff0c;还是保留当前神经元得到的隐藏层的信息多。 Bi-GRU GRU比LSTM参数少 …

升级iOS 17出现白苹果、不断重启等系统问题怎么办?

iOS 17发布后了&#xff0c;很多果粉都迫不及待的将iphone/ipad升级到最新iOS17系统&#xff0c;体验新系统功能。 但部分果粉因硬件、软件的各种情况&#xff0c;导致升级系统后出现故障&#xff0c;比如白苹果、不断重启、卡在系统升级界面等等问题。 如果遇到了这些系统问题…

【MQTT接收数据写入数据库】

MQTT接收数据写入数据库 1.搭建MQTT服务器 参考上一篇文章 2.安装数据库mysql sudo apt update sudo apt install mysql-server创建一个数据库和数据表存储mqtt消息 首先&#xff0c;登录到MySQL服务器&#xff1a; mysql -u root -p输入你的root用户密码。默认root 3.创…

sqlserver数据库链接mysql服务器访问数据

sqlserver数据库链接mysql服务器访问数据 关于SqlServer数据库怎么链接mysql数据库我一直不明白&#xff0c;今天项目碰到一个问题需要链接&#xff0c;我就研究了一下&#xff0c;然后就成功了&#xff0c;在这里记录一下。也欢迎朋友互相学习交流借鉴。 1.使用navicat打开S…

【EI/SCOPUS会议征稿】第二届环境遥感与地理信息技术国际学术会议(ERSGIT 2023)

第二届环境遥感与地理信息技术国际学术会议 2023 2nd International Conference on Environmental Remote Sensing and Geographic Information Technology 第二届环境遥感与地理信息技术国际学术会议&#xff08;ERSGIT 2023&#xff09;定于2023年11月10-12日在中国陕西西安…

Hadoop的第二个核心组件:MapReduce框架第二节

Hadoop的第二个核心组件&#xff1a;MapReduce框架第二节 六、MapReduce的工作流程原理&#xff08;简单版本&#xff09;七、MapReduce中的序列化机制问题八、流量统计案例实现&#xff08;序列化机制的实现&#xff09; 六、MapReduce的工作流程原理&#xff08;简单版本&…

Lua03——开发环境搭建

1 安装开发插件 在 idea 或 vscode 中安装 lua 的开发插件 EmmyLua 2 创建工程 在 idea 中创建一个新的工程 工程的类型选择 lua 输入工程名及目标目录 在工程结构的SDK中设置lua在本地安装目录 在工程结构的modules中选择 lua 3 编写第一个lua程序 在工程下添加程序包&#…

阿里云服务器怎么退款?云服务器退款流程图

阿里云服务器如何退款&#xff1f;云服务器在哪申请退款&#xff1f;在用户中心订单管理中的退订管理中退款&#xff0c;阿里云百科分享阿里云服务器退款流程&#xff0c;包括申请退款入口、云服务器退款限制条件、退款多久到账等详细说明&#xff1a; 目录 阿里云服务器退款…

解决readme.md文件中粘贴的图片放到GitHub上无法显示问题

问题原因 GitHub的README.md文件通常无法直接引用本地文件或图片&#xff0c;因为GitHub的README.md是在远程服务器上渲染和显示的&#xff0c;无法访问本地文件系统。 解决方案 要在GitHub的README.md中显示图片&#xff0c;你需要将图片上传到GitHub上&#xff0c;然后使用图…

pycharm创建py文件时自动添加基础信息--模板

在图片中加入下面基本信息&#xff0c;这些基本信息可以自己定义&#xff1a; #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : ${DATE} ${TIME} # Author : supermps # File : ${NAME}.py # Software : ${PRODUCT_NAME} import logging import math import w…

TreeList 的 增加、删除节点-----DevExpress

private void FrmDictionaryManaged_Load(object sender, EventArgs e){// treeList1.DataSource CreateDataTable();treeList2.DataSource CreateTreeList();// 绑定TreeList控件到数据源treeList1.DataSource GetData();treeList1.KeyFieldName "ID";treeList1.…

两种解法解决 LeetCode 27. 移除元素【C++】

移除元素 27. 移除元素题目&#xff1a;[移除元素](https://leetcode.cn/problems/remove-element/description/)示例和提示&#xff1a;解法&#xff1a;1. 暴力解法 2. 快慢指针 27. 移除元素 题目&#xff1a;移除元素 示例和提示&#xff1a; 解法&#xff1a; 1. 暴力解…

嵌入式面试/笔试C相关总结

1、存储 单片机端编译后分为code ro rw zi几个区域&#xff0c;其中code是执行文件&#xff0c;ro(read only)只读区域&#xff0c;存放const修饰常量、字符串。rw(read write)存放已初始化变量。zi存放未初始化变量。编译完成后bin大小为coderorw。运行时所需内存为rwzi。 在电…

【狂神】Spring5笔记(四)之Mybatis和事物的整合

一、整合Mybatis方式一 目录结构&#xff1a; 大致内容结构&#xff1a; 主要难点就在于applicationContext.xml中相关配置的理解 代码图片如下 这个类就专门用于对象的创建就可以了 测试类&#xff1a; 实现类&#xff1a; SqlSessionTemplate 二、整合Mybatis方式二 相关代码…