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://www.hqwc.cn/news/575675.html

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

相关文章

Windows 最佳文件管理器:快速、简单、直观、自由 | 开源日报 No.175

files-community/Files Stars: 30.6k License: MIT Files 是为 Windows 构建的最佳文件管理器应用程序。该项目解决了在 Windows 上进行文件管理时的困难。 它具有以下主要功能和优势&#xff1a; 采用直观设计&#xff0c;使浏览文件变得更加简单支持标签、预览和自定义背景…

uni-app(使用阿里图标)

1.注册阿里矢量图标库 注册阿里图标库账号并登录&#xff0c;https://www.iconfont.cn/ 2.加入购物车 搜索适合自己的图标&#xff0c;加入购物车&#xff0c;如下图&#xff1a; 3.加入项目 我的->资源管理->我的项目->创建项目&#xff0c;然后返回购物车&#…

前端学习-CSS基础-Day3

一、CSS三大特性 1.1层叠性 相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖&#xff08;层叠&#xff09;另一个冲突的样式。层叠性主要解决样式冲突的问题 层叠性原则&#xff1a; 1.样式冲突&#xff0c;遵循的原则是就近原则&#xff0c;哪个样式离结构近&a…

Flink集群主节点JobManager启动分析

1.概述 JobManager 是 Flink 集群的主节点&#xff0c;它包含三大重要的组件&#xff1a; ResourceManager Flink集群的资源管理器&#xff0c;负责slot的管理和申请工作。 Dispatcher 负责接收客户端提交的 JobGraph&#xff0c;随后启动一个Jobmanager&#xff0c;类似 Yarn…

【JavaEE初阶系列】——多线程案例四——线程池

目录 &#x1f6a9;什么是线程池 &#x1f388;从池子中取效率大于新创建线程效率(why) &#x1f6a9;标准库中的线程池 &#x1f388;为什么调用方法而不是直接创建对象 &#x1f388;工厂类里的方法 &#x1f4dd;newCachedThreadPool() &#x1f4dd;newFixedThread…

vscode使用sftp上传

1.用vscode打开项目 2.安装一下这个sftp 3.使用快捷键 ctrlshiftP 打开指令窗口&#xff0c;输入 sftp:config&#xff0c;选中回车&#xff0c;在当前目录中会自动生成 .vscode 文件夹及 sftp.json 4.修改sftp.json文件配置&#xff0c;改成以下&#xff08;默认的参数可能上传…

常用的8个应用和中间件的Docker运行示例

文章目录 1、Docker Web 管理工具 portainer2、在线代码编辑器 Code Server3、MySQL4、Redis5、Nginx6、PostgreSQL7、媒体管理工具 Dim8、Gitlab 1、Docker Web 管理工具 portainer Portainer 是一个轻量级的管理 UI &#xff0c;可让你轻松管理不同的 Docker 环境&#xff0…

github | ssh拉取github仓库报错connect to host github.com port 22: Connection refused

配置ssh key 通过 ssh key 解决本地和服务器连接的问题 $ cd ~/. ssh #检查本机已存在的ssh密钥 如果提示 No such file or directory 则表示第一次使用git 输入&#xff1a; ssh-keygen -t rsa -C "邮件地址" 并且连续3次回车&#xff0c;最终会生成一个文件&am…

第二证券今日投资参考:低空经济迎利好 自动驾驶商业化提速

昨日&#xff0c;两市股指盘中弱势震动&#xff0c;午后加快下探&#xff0c;沪指失守3000点大关&#xff0c;深成指、创业板指跌超2%&#xff1b;到收盘&#xff0c;沪指跌1.26%报2993.14点&#xff0c;深成指跌2.4%报9222.47点&#xff0c;创业板指跌2.81%报1789.82点&#x…

Redis命令-List命令

4.6 Redis命令-List命令 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与LinkedList类似&#xff1a; 有序元素可以重复插入和删除快查询速度一般 常用来存储一个有序数据&#xff…

【aws】架构图工具推荐

碎碎念 以前以为日本冰箱论是个梗&#xff0c;结果居然是真的。用光盘传真其实还能理解&#xff08;毕竟我也喜欢电子古董2333&#xff09;&#xff0c;但是画架构图居然用的是excel&#xff0b;截图&#xff01;啊苍天呐&#xff0c;然后看到隔壁工位用excel画web原型又感觉释…

【网络安全】常见的网站攻击方式及危害

常见的网站攻击方式多种多样&#xff0c;每一种都有其独特的特点和危害。以下是一些常见的网站攻击方式&#xff1a; 跨站脚本攻击&#xff08;XSS&#xff09;&#xff1a;攻击者通过在目标网站上注入恶意脚本&#xff0c;当用户浏览该网站时&#xff0c;恶意脚本会在用户的浏…