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() {
                    @Override
                    public void run() {
                        System.out.println("I love lele"+id);
                    }
                });
            }
    }
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】6.MySQL主从复制和读写分离

主从复制 主从复制与读写分离 通常数据库的读/写都在同一个数据库服务器中进行&#xff1b; 但这样在安全性、高可用性和高并发等各个方面无法满足生产环境的实际需求&#xff1b; 因此&#xff0c;通过主从复制的方式同步数据&#xff0c;再通过读写分离提升数据库的并发负载…

【微服务】Nacos(配置中心)

文章目录 1.AP和CP1.基本介绍2.说明 2.Nacos配置中心实例1.架构图2.在Nacos Server加入配置1.配置列表&#xff0c;加号2.加入配置3.点击发布&#xff0c;然后返回4.还可以编辑 3. 创建 Nacos 配置客户端模块获取配置中心信息1.创建子模块 e-commerce-nacos-config-client50002…

快速编译嵌入式Linux(4.9.229)内核(硬件:mini2440)

目录 概述 1 Linux内核介绍 1.1 Linux 内核版本 1.2 下载Linux 内核 2 编译内核 2.1 解压内核 2.2 编译环境 2.3 编译内核 概述 本文主要以硬件板卡mini2440为例&#xff0c;介绍如何从linux内核官网下载一个原生态的内核源码包&#xff0c;通过简单的配置编译适合在AR…

誉天华为认证云计算课程如何

HCIA-Cloud Computing 5.0 课程介绍&#xff1a;掌握华为企业级虚拟化、桌面云部署&#xff0c;具备企业一线部署实施及运维能力 掌握虚拟化技术、网络基础、存储基础等内容&#xff0c;拥有项目实施综合能力 满足企业虚拟化方案转型需求&#xff0c;应对企业日益多样的业务诉求…

excel中批量插入分页符

excel中批量插入分页符&#xff0c;实现按班级打印学生名单。 1、把学生按照学号、班级排序好。 2、选择班级一列&#xff0c;点击数据-分类汇总。汇总方式选择计数&#xff0c;最后三个全部勾选。汇总结果一定要显示在数据的下发&#xff0c;如果显示在上方&#xff0c;后期…

typescript 实现RabbitMQ死信队列和延迟队列 订单10分钟未付归还库存

Manjaro安装RabbitMQ 安装 sudo pacman -S rabbitmq rabbitmqadmin启动管理模块 sudo rabbitmq-plugins enable rabbitmq_managementsudo rabbitmq-server管理界面 http://127.0.0.1:15672/ 默认用户名和密码都是guest。 要使用 rabbitmqctl 命令添加用户并分配权限&#xf…

RTOS线程切换的过程和原理

0 前言 RTOS中最重要的一个概念就是线程&#xff0c;线程的按需切换能够满足RTOS的实时性要求&#xff0c;同时能将复杂的需求分解成一个个线程执行减轻我们开发负担。 本文从栈的角度出发&#xff0c;详细介绍RTOS线程切换的过程和原理。 注&#xff1a;本文参考的RTOS是RT-T…

Typora字数过多的时候造成卡顿现象如何解决?

Typora字数过多的时候造成卡顿现象如何解决&#xff1f; 点击 、切换、滚动、打字都有点卡顿&#xff0c;下面介绍三种方法&#xff0c;三种方法都可以尝试&#xff0c;建议先尝试方法一&#xff0c;效果不满意就用方法二&#xff0c;实在不行就最后一个取巧的办法。 方法1&a…

Unity TMP 使用教程

文章目录 1 导入资源包2 字体制作3 表情包制作4 TMP 控件4.1 属性4.2 富文本标签 1 导入资源包 “Window -> TextMeshPro -> Import TMP Essential Resources”&#xff0c;导入完成后会创建一个名为"TextMehs Pro"的文件夹&#xff0c;这里面包含所需要的资源…

Maya 2024 for Mac/Win:重塑三维创意世界的利器

在数字化浪潮汹涌的当下&#xff0c;三维图形软件早已成为创意产业不可或缺的重要工具。而在这其中&#xff0c;Maya 2024以其卓越的性能和丰富的功能&#xff0c;赢得了无数设计师的青睐。无论是Mac还是Win平台&#xff0c;Maya 2024都能为您的三维创作提供强大的支持。 Maya…

Docker部署MinIO对象存储服务

1. 拉取MinIO镜像 # 下载镜像 docker pull minio/minio#查看镜像 docker images2. 创建目录 # 文件存储目录 mkdir -p /opt/minio/data# 配置文件 mkdir -p /opt/minio/config# 日志文件 mkdir -p /opt/minio/logs3. 创建Minio容器并运行 docker run \ -p 9000:9000 \ -p 90…

ES学习日记(二)-------集群设置

上一节写了elasticsearch单节点安装和配置,现在说集群,简单地说就是在多台服务器上搭建单节点,在配置文件里面增加多个ip地址即可,过程同单节点部署,主要说集群配置 注意:不建议在之前单节点es上修改配置为集群,据说运行之后会生成很多文件,在单点基础上修改容易出现未知问题,…

zedboard+AD9361 运行 open WiFi

先到github上下载img&#xff0c;网页链接如下&#xff1a; https://github.com/open-sdr/openwifi?tabreadme-ov-file 打开网页后下载 openwifi img 用win32 Disk lmager 把文件写入到SD卡中&#xff0c;这一步操作会把SD卡重新清空&#xff0c;注意保存数据。这个软件我会…

最小可行产品需要最小可行架构——可持续架构(三)

前言 最小可行产品&#xff08;MVP&#xff09;的概念可以帮助团队专注于尽快交付他们认为对客户最有价值的东西&#xff0c;以便在投入大量时间和资源之前迅速、廉价地评估产品的市场规模。MVP不仅需要考虑产品的市场可行性&#xff0c;还需要考虑其技术可行性&#xff0c;以…

【JavaWeb】Day24.Web入门——HTTP协议(一)

HTTP协议——概述 1.介绍 HTTP&#xff1a;Hyper Text Transfer Protocol(超文本传输协议)&#xff0c;规定了浏览器与服务器之间数据传输的规则。 http是互联网上应用最为广泛的一种网络协议http协议要求&#xff1a;浏览器在向服务器发送请求数据时&#xff0c;或是服务器在…

Oracle存数字精度问题number、binary_double、binary_float类型

--表1 score是number(10,5)类型 create table TEST1 (score number(10,5) ); --表2 score是binary_double类型 create table TEST2 (score binary_double ); --表3 score是binary_float类型 create table TEST3 (score binary_float );实验一&#xff1a;分别往三张表插入 小数…

Redis开源协议变更!Garnet:微软开源代替方案?

Garnet&#xff1a;微软开源的高性能替代方案&#xff0c;秉承兼容 RESP 协议的同时&#xff0c;以卓越性能和无缝迁移能力重新定义分布式缓存存储&#xff01; - 精选真开源&#xff0c;释放新价值。 概览 最近&#xff0c;Redis修改了开源协议&#xff0c;从BSD变成了 SSPLv…

青龙脚本 猫猫看看

话不多说开图 https://raw.githubusercontent.com/Huansheng1/my-qinglong-js/main/%E7%8C%AB%E7%8C%AB%E7%9C%8B%E7%9C%8B.py

探索Python人工智能在气象监测中的创新应用

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;在数据处理、科学计算、数学建模、数据挖掘和数据可视化方面具备优异的性能&#xff0c;这些优势使得Python在气象、海洋、地理、气候、水文和生态等地学领域的科研和工程项目中得到广泛应用。可以…

Jupyter安装教程(Windows 版)

这几年AI人工智能这么火&#xff0c;陆陆续续诞生了很多新的产品&#xff0c;新的商业模式&#xff0c;随着Open-sora 1.0开源之后&#xff0c;让我更加地相信GPT5也即将要到来了&#xff0c;看来不学机器学习和深度学习&#xff0c;恐怕是要跟不上时代了。于是就想着今年开始接…