【并发编程篇】源码分析,手动创建线程池

文章目录

  • 🛸前言
    • 🌹Executors的三大方法
  • 🍔简述线程池
  • 🎆手动创建线程池
    • ⭐源码分析
    • ✨代码实现,手动创建线程池
      • 🎈CallerRunsPolicy()
      • 🎈AbortPolicy()
      • 🎈DiscardPolicy()
      • 🎈DiscardOldestPolicy()

在这里插入图片描述

🛸前言

🌹Executors的三大方法

Java 中的 Executors 类提供了创建和管理线程池的工厂方法。主要有以下三种常用的静态工厂方法:

  • newFixedThreadPool(int nThreads):固定的线程池大小
    创建一个固定大小的线程池,其中包含指定数量的线程。如果所有线程都处于活动状态,并且任务队列已满,那么新任务将在任务队列中等待,直到有空闲的线程可用。
    在这里插入图片描述

  • newCachedThreadPool():遇强则强,遇弱则弱
    创建一个可缓存的线程池,如果线程池的当前规模超过处理需求时,它会回收空闲线程;当需求增加时,则可以添加新的线程,线程池规模不存在限制。

在这里插入图片描述

  • newSingleThreadExecutor(): 单个线程
    创建一个单线程的线程池,该线程池只有一个工作线程,它保证所有任务按顺序执行。

在这里插入图片描述

这些工厂方法都返回实现了 ExecutorService 接口的 ThreadPoolExecutor 对象,这是 Java 线程池的一个具体实现,提供了对线程池的操作和控制。通过使用这些工厂方法创建线程池,可以方便快捷地满足不同场景下的线程管理需求。


请添加图片描述
由于使用Executors不安全,那么我们需要手动创建一个线程池

🍔简述线程池

线程池是一种用于管理和重用线程的机制,它通过预先创建一组线程,并将任务提交给这些线程来执行。线程池可以有效地控制并发线程的数量,避免了频繁创建和销毁线程的开销,提高了系统的性能和资源利用率。

线程池通常由以下组件构成:

  • 线程池管理器(ThreadPoolExecutor):负责创建、管理和调度线程池中的线程。它维护着一个线程池的状态,包括线程数量、任务队列、线程工厂等属性。
  • 工作线程(Worker Thread):线程池中的实际执行任务的线程。线程池会创建一定数量的工作线程,每个工作线程可以执行多个任务。
  • 任务队列(Task Queue):用于存储待执行的任务。当线程池中的线程空闲时,它们会从任务队列中获取任务并执行。
  • 线程工厂(Thread Factory):用于创建新的线程对象。线程池在需要创建新线程时,会使用线程工厂创建线程对象。

线程池的主要优点包括:

  • 提高系统性能:线程池可以控制并发线程的数量,避免了过多的线程竞争和频繁的线程创建销毁开销,提高了系统的性能。
  • 提高资源利用率:线程池可以重用线程,避免了线程创建和销毁的开销,提高了系统的资源利用率。
  • 提供线程管理和监控:线程池提供了对线程的管理和监控机制,可以方便地查看线程池的状态、线程执行情况等信息,便于调优和排查问题。

使用线程池时,需要根据具体的业务需求和系统资源情况合理配置线程池的大小、任务队列的容量以及其他相关参数,避免因线程池过小或过大导致的性能问题。

🎆手动创建线程池

⭐源码分析

newSingleThreadExecutor的源码
在这里插入图片描述newFixedThreadPool的源码
在这里插入图片描述newCachedThreadPool的源码
在这里插入图片描述其中有个参数长度是Integer,MAX_VALUE,长度过大,可能会堆积大量的请求,对应了上面我们说的不能用Executors,而要用ThreadPoolExecutors

我们发现,上面三者的源码中都有ThreadPoolExecutor
说明调用线程的本质调用的是ThreadPoolExecutor

下面我们来分析一下ThreadPoolExecutor
在这里插入图片描述在这里插入图片描述下面我们来想象一个场景,来更好的理解线程池
比如我们去银行办理业务
银行有5个窗口,但是只打开了2个(代表核心线程池的大小为2),还有3个没有开(触发最大并发量的情况下才会打开这3个窗口),还有容量为3的候客区(阻塞队列)
然后有用户去办理业务了,假如来了3个用户,2个去窗口了,还有1个在候客区等待,此时,又来了3个用户,这时候客区的位置不够了(阻塞队列满了),就要打开那关闭的3个窗口(触发最大并发量了)

✨代码实现,手动创建线程池

🎈CallerRunsPolicy()

package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定义线程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS,   //超时等待时间new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());try {for (int i = 1; i <= 10; i++) {//使用线程池后,使用线程池来创建线程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//关闭线程池threadPool.shutdown();}}
}

在这里插入图片描述

代码里面的超时等待时间是什么意思
我们对应上面去银行的场景,触发最大并发条件后,所有窗口都打开了,一段时间后,所有用户都离开了,过了设定的时间都没有业务,那么后面3个窗口就要关闭

🎈AbortPolicy()

package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定义线程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS,   //超时等待时间new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());try {for (int i = 1; i <= 10; i++) {//使用线程池后,使用线程池来创建线程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//关闭线程池threadPool.shutdown();}}
}

在这里插入图片描述

🎈DiscardPolicy()

package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定义线程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS,   //超时等待时间new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());try {for (int i = 1; i <= 10; i++) {//使用线程池后,使用线程池来创建线程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//关闭线程池threadPool.shutdown();}}
}

丢掉任务,但是不会抛出异常

在这里插入图片描述

🎈DiscardOldestPolicy()

package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定义线程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS,   //超时等待时间new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());try {for (int i = 1; i <= 10; i++) {//使用线程池后,使用线程池来创建线程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//关闭线程池threadPool.shutdown();}}
}

在这里插入图片描述

在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!

在这里插入图片描述

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

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

相关文章

JOSEF约瑟LB-8断相闭锁继电器 额定电压 100V 额定频率 50Hz 面板嵌入式安装

系列型号 LB-7有电闭锁继电器 LB-1D型有电闭锁继电器 LB-8闭锁继电器 1用途 LB-8闭锁继电器用于电厂和变电站内&#xff0c;作为高压母线合接刀闸的闭锁元件。以防止高压母线带电时接地刀闸。 2接线图 接线图 3技术参数与特性 动作特性&#xff1a;继电器施加三相交流…

MongoDB数据库本地部署并结合内网穿透实现navicat公网访问

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 前言 MongoDB是一个基于分布式文件存储的数…

TensorFlow 模型中的回调函数与损失函数

回调函数 tf.keras 的回调函数实际上是一个类&#xff0c;一般是在 model.fit 时作为参数指定&#xff0c;用于控制在训练过程开始或者在训练过程结束&#xff0c;在每个 epoch 训练开始或者训练结束&#xff0c;在每个 batch 训练开始或者训练结束时执行一些操作&#xff0c;…

FPGA-ZYNQ-7000 SoC在嵌入式系统中的优势

FPGA-ZYNQ-7000 SoC在嵌入式系统中的优势 本章节主要参考书籍《Xilinx Zynq-7000 嵌入式系统设计与实现 基于ARM Cortex-A9双核处理器和Vivado的设计方法 (何宾&#xff0c;张艳辉编著&#xff09;》 本章节主要讲述FPGA-ZYNQ-7000 SoC在嵌入式系统中的优势&#xff0c;学习笔…

调用openssl api函数C代码生成CSR文件

概述&#xff1a; 本文基于本人之前的一篇文章的延伸&#xff0c;调用openssl api函数C代码生成证书&#xff1a;https://blog.csdn.net/shenweihong/article/details/125140149&#xff0c; 本文使用的公钥类型RSA&#xff0c;签名私钥类型也是RSA 软件环境&#xff1a; op…

数据通信网络基础华为ICT网络赛道

目录 前言&#xff1a; 1.网络与通信 2.网络类型与网络拓扑 3.网络工程与网络工程师 前言&#xff1a; 数据通信网络基础是通信领域的基本概念&#xff0c;涉及数据传输、路由交换、网络安全等方面的知识。华为ICT网络赛道则是华为公司提出的一种技术路径&#xff0c;旨在通…

大模型做实体识别任务的原理

1、背景 命名实体识别&#xff08;named entity recognition&#xff0c;NER&#xff09;&#xff1a;通常是一个序列标注的任务&#xff0c;常见的模型框架有&#xff1a;LSTM-CRF、BERTBILSTMCRF等&#xff0c;该种任务通常被成为flat NER即&#xff1a;每一个token只分配一…

20231225使用亿佰特的蓝牙模块dongle协议分析仪E104-2G4U04A抓取BLE广播数据

20231225使用亿佰特的蓝牙模块dongle协议分析仪E104-2G4U04A抓取BLE广播数据 结论&#xff1a;硬件蓝牙分析仪 不一定比 手机端的APK的效果好&#xff01; 亿佰特E104-2G4U04A需要3片【单通道】&#xff0c;电脑端的UI为全英文的。 BLE-AnalyzerPro WCH升级版BLE-PRO蓝牙分析仪…

Arduino驱动BME680四合一传感器模块

目录 一、简介二、技术参数三、使用方法四、实验现象 一、简介 点击图片购买 GYMCU680 是一款低成本空气检测模块&#xff0c;工作电压 3-5v 功耗小&#xff0c;体积小。其工作原理&#xff0c;是通过 MCU 读取 BME680传感器数据&#xff0c;经过算法得到&#xff0c;温湿度&am…

Error loading MySQLdb module.Did you install mysqlclient?报错解决方法

出现报错django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module. Did you install mysqlclient? 这个错误意味着你的Django项目在尝试使用MySQL数据库时找不到MySQLdb模块。 首先检查自己有没有安装mysqlclient 运行以下命令来安装mysqlclient&…

Spring之国际化:i18n

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

玩转大数据22:常见的关联规则挖掘算法

引言 关联规则挖掘是数据挖掘中的一种重要技术&#xff0c;主要用于发现数据集中项之间的有趣关系。关联规则挖掘在许多领域都有广泛的应用&#xff0c;如市场篮子分析、推荐系统等。常见的关联规则挖掘算法包括Apriori算法和FP-Growth算法。 一、Apriori算法 关联规则挖掘是…