JAVAEE——线程池

文章目录

  • 线程池的概念
    • 什么是线程池?
  • 标准库中的线程池
    • 线程池的创建
    • 工厂模式
    • 工厂模式的用途
    • 线程池涉及到的类有哪些
      • Executor接口
      • ExecutorService接口
      • Executors工厂类
      • AbstractExecutorService虚类
      • ThreadPoolExecutor普通类
        • ThreadPoolExecutor内部的实现4个拒绝策略
  • 线程池的实现
    • 实现线程池

线程池的概念

什么是线程池?

我们先来说一下什么是线程池,线程池这个名字大家应该能够有一定的了解,我们计算机中进程会用到池化技术,
在这里插入图片描述
所谓池化技术,它其实就跟蓄水池一样,也就是提前创建好一批线程,并且不让其销毁,等到需要他们去做任务的时候再将其唤醒,这样子就可以有效的提高性能,至于为什么可以提高性能呢?我们通过一个例子来说明一下。
比如说我们要去银行取钱,那么有两种方式第一种就是通过柜台取钱,第二种就是通过ATM机自动取钱。
在这里插入图片描述
在这里插入图片描述
这时候就有了两种应对方式,如果是柜台的话你需要签名,出示证件,初始银行卡,然后输入密码,确认额度等等。办理起来就会很麻烦而且还得等待上班的时候才可以,但是我们老百姓就想取个多的话一两千少的话几百块因此不希望这么麻烦,所以就可以去ATM机去,这时候ATM就很方便只需要输入密码即可。而线程池也是这个道理,我们会提前创造好一部分线程放入我们创造的一块内存空间中,等到需要的时候在调用这个线程池里的线程,这样子我们就可以大幅度的缩小时间的消耗非常的高效。

标准库中的线程池

线程池的创建

首先我们来说一下如何创建一个线程池呢?这里涉及到了几个知识点我们来说一下。

使用 Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.
返回值类型为 ExecutorService
通过 ExecutorService.submit 可以注册一个任务到线程池中.

我们来写一段代码。

public class Main {public static void main(String[] args) {ExecutorService executorService=Executors.newFixedThreadPool(10);}
}

这样子我们就创建了一个含有十个线程的线程池,这时候有的同学就有疑问了,为什么这里我们创建线程池的时候涉及到了两个类,一般不都是一个类然后new一下吗?就像我们创建线程一样,这是为什么呢?这里涉及到了一个模式叫做工厂模式

工厂模式

什么是工厂模式呢?我们举个例子假设说我们去买个本子,我们想买有一百张纸的本子,这时候店家肯定不会像A4纸那样给我们一张一张的本子肯定是,生产了一百张纸然后将这一百张纸进行装订和包装从而交到我们手上。那么什么地方要用到工厂模式呢?

工厂模式的用途

我们应该都知道函数重载吧。那么如果说存在这样一种情景,就是你需要写一个除法算法但是两个除法算法的要求不一样第一个方法的要求是返回值必须得保留两位小数,第二个方法的要求是保留三位小数并且必须和第一个方法的名字一样用重载实现。这时候就会有人说了怎么会有这么离谱的要求,是的如果放在这里干说确实很离谱但是如果是类里面的构造方法呢?构造方法的方法名称一样唯一能构成重载的就是参数类型,可是会不会有一些场景即使是参数类型也完全一样呢?答案是肯定的并且由于这是构造方法导致我们的函数名称还不能发生改变,因此最好的解决办法是什么呢?那就是再创造一个类这个类里面包含了很多我们需要的方法,接下来我们想要创建哪种类型只需要从这个类里面进行完成就可以了。这个就是工厂模式也就是我们上面的那个代码的来源。

线程池涉及到的类有哪些

我们打开源代码来看一些东西

Executor接口

任务执行器(Executor)是一个接口,位于java.util.concurrent包下,它的作用主要是为我们提供任务与执行机制(包括线程使用和调度细节)之间的解耦。比如我们定义了一个任务,我们是通过线程池来执行该任务,还是直接创线程来执行该任务呢?通过Executor就能为任务提供不同的执行机制。执行器的实现方式各种各样,常见的包括同步执行器、一对一执行器、线程池执行器、串行执行器等等。这个接口内部只有一个方法。如下图
在这里插入图片描述

ExecutorService接口

ExecutorService 主要用来管理和控制线程,是Java并发编程的重要工具,在实际业务中, ExecutorService 的使用场景非常广泛,比如,经常需要处理大量的用户请求,而每个请求都需要一个独立的线程去处理,如果直接为每个请求创建一个新的线程,会消耗大量的系统资源,而且管理起来也非常麻烦,此时,就可以使用ExecutorService来解决问题。这时候我们有个问题这个东西是个接口啊,接口是不能实例化处对象的,那么为什么刚刚那个工厂类中的创建线程池方法可以直接返回给这个接口呢?其实那个方法里所创造的对象根本不是这个接口的实例化,而是它的子类。因此这里其实涉及到了一个向上转型。

Executors工厂类

Executors是Java中用于创建线程池的工厂类,它提供了一系列的静态工厂方法,用于创建不同类型的线程池。这些工厂方法隐藏了线程池的复杂性,使得线程池的创建变得非常简单。Executors工厂类提供的线程

  • newCachedThreadPool():创建一个可缓存的线程池。这个线程池的线程数量可以根据需要自动扩展,如果有可用的空闲线程,就会重用它们;如果没有可用的线程,就会创建一个新线程。适用于执行大量的短期异步任务。
  • newSingleThreadExecutor():创建一个单线程的线程池。这个线程池中只包含一个线程,用于串行执行任务。适用于需要按顺序执行任务的场景。
  • newFixedThreadPool(int nThreads):创建一个固定大小的线程池,其中包含指定数量的线程。线程数量是固定的,不会自动扩展。适用于执行固定数量的长期任务。
  • newScheduledThreadPool(int corePoolSize):创建一个固定大小的线程池,用于定时执行任务。线程数量固定,不会自动扩展。适用于定时执行任务的场景。
  • newWorkStealingPool(int parallelism):创建一个工作窃取线程池,线程数量根据CPU核心数动态调整。适用于CPU密集型的任务。
  • newSingleThreadScheduledExecutor():创建一个单线程的定时执行线程池。只包含一个线程,用于串行定时执行任务。

AbstractExecutorService虚类

AbstractExecutorService实现了ExecutorService和Executor接口的基本方法,ThreadPoolExecute和ForkJoinPool继承AbstractExecutorService就可以减少实现的复杂度,接口适配器模式

ThreadPoolExecutor普通类

他是线程池的真正的实现类内部有很多实现细节

ThreadPoolExecutor内部的实现4个拒绝策略

我们保存任务

CallerRunsPolicy:由调用execute方法提交任务的线程来执行这个任务
AbortPolicy:抛出异常RejectedExecutionException拒绝提交任务
DiscardPolicy:直接抛弃任务,不做任何处理
DiscardOldestPolicy:去除任务队列中的第一个任务,重新提交

线程池的实现

实现线程池

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class threadPool {private BlockingQueue<Runnable>blockingQueue=new ArrayBlockingQueue<>(10000);public void submit(Runnable runnable){try {blockingQueue.put(runnable);} catch (InterruptedException e) {throw new RuntimeException(e);}}public threadPool(int n){for(int i=0;i<4;i++){Thread thread=new Thread(()->{while(true){try {Runnable runnable=blockingQueue.take();runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();}}}
import java.beans.ExceptionListener;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;public class Main {public static void main(String[] args) {threadPool th=new threadPool(100);for(int i=0;i<1000;i++){int id=i;th.submit(new Runnable() {@Overridepublic void run() {System.out.println("I love lele"+id);}});}}
}

那么以上代码就是我们创建线程池的代码这个代码结构相对是比较简单的。一个阻塞队列用来存储执行的任务然后创建线程去执行任务因为阻塞队列是线程安全的,因此当无任务的时候创建的线程会陷入等待状态中。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

(C++) 属性说明符-语法

文章目录 前言语法&#x1f3f7;️非标准语法⭐GCC⭐MSVC &#x1f3f7;️[[ 属性列表 ]] (C11 起)⭐标识符⭐属性命名空间::标识符⭐标识符(实参列表 &#xfeff;(可选) )⭐同时多个属性 &#x1f3f7;️[[ using 属性命名空间 : 属性列表 ]] (C17 起)&#x1f3f7;️解释⭐…

图解Dijkstra和Bellman-Ford的流程以及证明

说到寻路&#xff0c;在游戏里面应用最多的自然还是A寻路&#xff0c;但是这篇文章不讨论A寻路&#xff0c;主要是介绍Dijkstra和Bellman-Ford&#xff0c;因为这两个寻路核心代码少&#xff0c;但是正确性却不容易直接看出来&#xff0c;网上的博客也基本都是画步骤告诉大家怎…

Linux内核之最核心数据结构之一:struct file(三十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

产品SDK化转型:标准化与机构个性化定制解决方案

一、背景 在互联网行业中&#xff0c;企业通常可分为两大类别&#xff1a;2C和2B。对于2B企业而言&#xff0c;它们的产品往往以产品的形式提供给各个合作机构。以金融领域为例&#xff0c;一家2B金融公司通常将产品销售给各个银行和证券公司&#xff0c;这是2B领域常见的做法…

2.11 Python关键字(保留字)

Python关键字&#xff08;保留字&#xff09;一览表 保留字是Python 语言中一些已经被赋予特定意义的单词&#xff0c;这就要求开发者在开发程序时&#xff0c;不能用这些保留字作为标识符给变量、函数、类、模板以及其他对象命名。 Python 包含的保留字可以执行如下命令进行…

企业网站建设的方法的相关问题的解决办法的问题

现在市场上比较大的公司都建立了自己的企业网站&#xff0c;比如华为、小米等&#xff0c;在他们的企业网站中&#xff0c;可以充分展示自己产品的优势&#xff0c;介绍公司的优质服务。 这都是让顾客改变购买想法的重要因素。 现在互联网发达了&#xff0c;很多人在购买产品的…

k8s局域网通过operator部署rabbitmq

参考&#xff1a;Installing RabbitMQ Cluster Operator in a Kubernetes Cluster | RabbitMQ 1、下载cluster-operator.yml wget https://github.com/rabbitmq/cluster-operator/releases/download/v2.7.0/cluster-operator.yml 2、拉取对应的镜像&#xff0c;这里的版本是根…

腾讯云4核8g服务器多少钱?2024轻量和CVM收费价格表

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

最优算法100例之10-数组中重复出现多次的数

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不…

安全的内网通讯软件,WorkPlus定制化 IM/办公门户解决方案

如今处于数字化转型的“加速期”&#xff0c;政企正经历着一场数字化迭代升级的时代浪潮。而不少企业都已具备了数字化管理的意识&#xff0c;数字化应用场景也在全面推开。WorkPlus不断推动信息技术与企业业务深度融合&#xff0c;作为安全的内网通讯软件&#xff0c;为企业提…

【算法刷题 | 二叉树 05】3.28(左叶子之和、找树 左下角的值)

文章目录 11.左叶子之和11.1问题11.2解法一&#xff1a;递归11.2.1递归思路11.2.2代码实现 11.3解法二&#xff1a;栈11.3.1栈思想11.3.2代码实现 12.找树左下角的值12.1问题12.2解法一&#xff1a;层序遍历 11.左叶子之和 11.1问题 给定二叉树的根节点 root &#xff0c;返回…

|行业洞察·汽车|《2024新能源汽车行业及营销趋势报告-20页》

报告的主要内容解读&#xff1a; 新能源汽车行业概述及品牌分布&#xff1a; 近年来&#xff0c;中国新能源汽车销量增速高&#xff0c;市场占有率快速提升&#xff0c;成为汽车行业的重要增量。新能源汽车消费者趋向年轻化、女性化和高端化&#xff0c;对高科技、新体验有较高…

LeetCode:718最长重复子数组 C语言

718. 最长重复子数组 提示 给两个整数数组 nums1 和 nums2 &#xff0c;返回 两个数组中 公共的 、长度最长的子数组的长度 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 输出&#xff1a;3 解释&#xff1a;长度最长的公共子数组是 [3,…

解决:npx nuxi@latest module add image 问题

背景 在 nuxtJS项目中使用内置组件 NuxtImg , 按照官方操作如下图进行安装&#xff0c;在npm run dev 时&#xff0c;出现了报错&#xff1a; "ipx" is imported by "node_modules/nuxt/image/dist/runtime/ipx.mjs", but could not be resolved – treat…

Unity 学习日记 12.小球撞击冰块游戏

目录 1.准备场景 2.让小球动起来 3.用鼠标把小球甩出去 4.加入鼠标点击小球的判断 5.小球与冰块的碰撞测试 6.撞击后销毁冰块 ​编辑 7.显示游戏计时 8.显示扔球次数 9.显示剩余冰块个数 10.游戏结束 11.完整代码 下载源码 UnityPackage 最终效果&#xff1a; 1.准…

机器学习(三)

神经网络: 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络&#xff0c;它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。 f为激活(响应)函数: 理想激活函数是阶跃函数&#xff0c;0表示抑制神经元而1表示激活神经元。 多层前馈网络结构: BP(误差逆…

Git命令上传本地项目至github

记录如何创建个人仓库并上传已有代码至github in MacOS环境 0. 首先下载git 方法很多 这里就不介绍了 1. Github Create a new repository 先在github上创建一个空仓库&#xff0c;用于一会儿链接项目文件&#xff0c;按照自己的需求设置name和是否private 2.push an exis…

步态采集平台

&#x1f349;步骤一、读取视频每一帧图像 &#x1f349;步骤二、对读取的图像进行分割&#xff0c;得到全景下的步态轮廓图。 ​​​​​​​&#x1f349;步骤三、对读取的图像进行裁剪得到归一化的步态轮廓图。 ​​​​​​​&#x1f349;步骤四、保存这一帧步态轮廓图

MongoDB Atlas维护指南:常见类型、注意事项与窗口设置

为了给Atlas用户更好的产品体验&#xff0c;MongoDB产品团队会进行定期维护。 本文将会介绍&#xff1a; 常见维护项目种类及频率&#xff0c;注意事项维护期间的影响及建议维护窗口设置说明维护告警设置和邮件通知范例 维护窗口常见项目 定期SSL证书轮换软件升级&#xff…

Git--08--Git分支合并操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Git分支合并操作案例流程客户端&#xff1a;GitExtensions操作步骤&#xff1a;A操作步骤&#xff1a;B操作步骤&#xff1a;C操作步骤&#xff1a;D操作步骤&#…