JavaEE:线程池精讲

news2024/9/20 15:08:25

目录

一.什么是线程池

二.线程池的实现原理

🎈为什么要有工厂模式?

三.线程池的构造方法解读

🎈线程池的拒绝策略

四.自己实现一个线程池


一.什么是线程池

简单来说,线程池就好比一块鱼塘,鱼塘中的每条鱼就是一个线程。那么为什么要有这个线程池呢?就好比 一个“渣女\渣男”,当他和A在一起的时候,如果想和B在一起,那么就需要先想办法和A分手,再和B搞好关系,最终和B在一起。如果她和A谈的时候,已经找好了B C D,此时就可以直接拿来无缝衔接~~

其实线程池也就大概这个作用,里面存放一些线程,需要用的时候直接拿来使用。

二.线程池的实现原理

我们先来看线程池是如何创建的:

package Pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class threadPoolDemo {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
    }
}

很明显,此处的线程池竟然不是 new 出来的,那么它是如何被实例化的呢?其实这里就使用了一种设计模式:工厂模式。

🎈为什么要有工厂模式?

其实工厂模式就时给Java中的构造方法填坑的,我们的构造方法其实时有很大缺陷的,我们来看以下例子。

我们期望这个Point类,初始化的时候能够传入 double x,double y,用来构造笛卡尔坐标系

我们又希望在不创建其他类的情况下,这个Point类, 初始化的时候能够传入 double r,double a,用来构造极坐标系。

但是构造方法也是方法,此时的方法由于参数个数和参数的类型都相同,就会编译失败,那么就没办法满足期望!

此时我们可以再写一个类:

此时这个类中又两个静态方法,一个是构造笛卡尔坐标系,并且返回。一个是构造及坐标系,并且返回对象。

那么我们就可以使用以下语句来分别调用:

Point p1 = PointFactory.makePintByXY(10,20) 

Point p2 = PointFactory.makePintByRA(12,63) 

此时通过PointFactory类,来给Point类传入需要的值就可以了。


那么线程池也是通过这样的方式来进行创建的:

三.线程池的构造方法解读

从Excutor这个工厂类的源码中可以得到以下:

其实线程的创建又被封装到了一个叫做ThreadPoolExecutor的类中

点开ThreadPoolExecutor,可以得到如下图片:

其中的每个参数的意思是这样的:

第一个是核心线程数, 第二个是最大线程数

线程池中的线程数目是可以动态变化的

范围就是【int corPoolSize. ~ int maxmumPoolSize】

什么是核心线程:

就好比一个公司中有正式员工(核心线程)和实习生,总的员工数目不能超过一定的值。当人手不够用就招实习生,这样既可以满足效率的需求,又可以避免过多的开销。

第三个是线程的可存活时间

第四个TimeUnit unit是用来设置非核心线程闲置超时时长(keepAliveTime)的单位。当一个非核心线程的闲置时间超过这个参数所设定的时长时,该线程就会被销毁掉。

第五个比较重要

第六个是线程池的拒绝策略,也就是当所有线程都处于忙碌状态,如果还往线程池中添加元素,线程池所做的操作。

这些构造方法,第一个和第五个以及第六个是需要重点掌握的。 

下面来单独讲讲第六个参数:拒绝策略

🎈线程池的拒绝策略

所谓的拒绝策略,其实就是如果线程池中每个线程都是处于忙碌的状态,如何应对新来的线程任务。

举个例子:如果我周一到周五都是满课,此时我一朋友让我给他去代课,那么此时我如何应对?此时就会有相应的应对策略:

  1. AbortPolicy(默认策略):这是默认的拒绝策略,它会抛出一个未检查的RejectedExecutionException,以指示任务被拒绝。也就是我本来都满课了,朋友还让我去代课,此时我就直接崩溃,代课和我自己的课我都不去上了,直接崩溃!
  2. CallerRunsPolicy:这个策略不会抛出异常。相反,它会将任务退回给调用线程,让它自己运行这个任务。 也就是让我朋友自己去上课。
  3. DiscardOldestPolicy:此策略会丢弃队列中等待最久的任务,并立即返回给调用者。也就是我丢弃我课程中一节课,去给他代课。
  4. DiscardPolicy:这个策略会静默地丢弃被拒绝的任务。也就是说,它不会抛出任何异常,也不会通知任务被拒绝。 也就是我拒绝去给他代课,我自己上自己的课。然后我朋友也不去上课了,那么这个课(任务) 也就黄了。

四.自己实现一个线程池

  实现线程池一个最关键的步骤就是拒绝策略,那么说明拒绝策略呢?

由于之前学过阻塞队列的知识,这里就先用阻塞队列来实现以下。

那么这个就是一种自己定义的新的拒绝策略,那就是一直等待~

package Pool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;


class MyPoolDemo {
    //一个队列
    BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    //通过这个方法,把任务添加到队列当中
    public void submit(Runnable task) throws InterruptedException {
        queue.put(task); //往阻塞队列中放入元素
    }

    public MyPoolDemo(int n) throws InterruptedException {
        //构造方法
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(() -> {
               //让这个线程从队列中消费任务并且进行执行
                try {
                    //如果队列中没有元素,那就阻塞等待
                    //一旦队列中有了任务,那么就立即执行take方法获取到任务并且开始执行
                        Runnable task = task = queue.take();
                        task.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            t.start();

        }
    }


}
public class RunDemo {
    public static void main(String[] args) throws InterruptedException {
        /**
         * 步骤理解:
         * 1.创建线程池并且指定线程数目是 20 ,在实例化线程池的时候已经创建好了20个线程
         * 2.这20个线程都在等待 take 获取到任务队列中的任务
         * 3.for 语句 循环 1000次,每次循环都会提交任务到任务队列
         * 4.一但任务队列里面有元素,这20个线程就会立马获取到,并且执行
         */
        MyPoolDemo myPoolDemo = new MyPoolDemo(20);
        int taskCount = 1000;
        while (true) {
            for (int i = 0; i < taskCount; i++) {
                int id = i;
                myPoolDemo.submit(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("执行任务:" + id);
                    }

                });
            }
        }
    }
    }

运行结果:

代码解读:

1.线程池里的线程是需要执行任务的,这个任务可以放到    BlockingQueue 这个阻塞队列中。为什么要使用阻塞队列呢?当线程池中的线程都在工作,此时就直接等待阻塞。

2.submit 方法接受一个实例化好的Runnable类型的任务,负责往队列中添加元素

3. MyPoolDemo(int n) 是这个类的构造放法,当实例化这个类的时候,被指定的 n 就是要创建的线程数量。

4. 由运行结果可以得出:当线程数量为20的时候,可以看到任务被随即执行完了。


总结:Java线程池是Java并发编程中一个重要的概念,它用于管理和控制线程的创建、销毁,以及任务提交和执行。线程池的主要目的是减少创建和销毁线程的开销,提高性能。 

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

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

相关文章

Ansys Lumerical|大尺寸超透镜的光线追迹仿真

附件下载 联系工作人员获取附件 前言 本文介绍了设计和模拟厘米尺度超透镜的工作流程。 我们将一系列不同直径的纳米尺寸等级单元(以下称为纳米单元)在Lumerical中建模&#xff0c;使用RCWA方法对每种直径的纳米单元进行分析&#xff0c;建立纳米元素直径以及其诱发的相位和…

【网络安全】-Linux操作系统基础

文章目录 Linux操作系统目录结构Linux命令格式Linux文件和目录操作命令Linux用户和用户组操作命令Linux查看和操作文件内容命令Linux文件压缩和解压缩命令Linux网络管理命令Linux磁盘管理和系统状态命令Linux安全加固总结 Linux是一个强大的操作系统&#xff0c;广泛用于服务器…

08‐Mysql全局优化与Mysql 8.0新特详解

文章目录 Mysql全局优化总结配置文件my.ini或my.cnf的全局参数最大连接数允许用户连接的最大数量MySQL能够暂存的连接数量JDBC连接空闲等待时长client连接空闲等待时长innodb线程并发数innodb存储引擎buffer pool缓存大小行锁锁定时间redo log写入策略binlog写入磁盘机制排序线…

html之CSS的高级选择器应用

文章目录 一、CSS高级选择器有哪些呢&#xff1f;二、高级选择器的应用1、层次选择器后代选择器子选择器相邻兄弟选择器通用兄弟选择器 2、结构伪类选择器&#xff08;不常用&#xff09;3、属性选择器E[attr]E[attrval]E[attr^val]E[attr$val]E[attr*val] 一、CSS高级选择器有…

大模型上下文扩展之YaRN解析:从直接外推ALiBi、位置插值、NTK-aware插值、YaRN

前言 下半年以来&#xff0c;我全力推动我司大模型项目团队的组建&#xff0c;我虽兼管整个项目团队&#xff0c;但为了并行多个项目&#xff0c;最终分成了三个项目组&#xff0c;每个项目都有一个项目负责人&#xff0c;分别为霍哥、阿荀、朝阳 在今年Q4&#xff0c;我司第…

ChatGPT引领AI时代:程序员、项目经理、产品经理、架构师、Python量化交易师的翅膀

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在当今AI时代&#xff0c;ChatGPT作为一项卓越…

Copilot帮我救回了变砖的甲骨文实例

最近&#xff0c;我的一个美国凤凰城的甲骨文永久免费的amd实例失联了&#xff0c;主要原因东西装多了就反应慢了&#xff0c;还常常断线&#xff0c;寻思干脆 dd个新的系统算了&#xff0c;但dd就后悔了&#xff0c;原来那些开放的端口都关闭了&#xff0c;仅留了一个ssh服务的…

25G/100G校园网解决方案

不断增长的视频流媒体、人工智能&#xff08;AI&#xff09;和云应用的流量需求推动了对更快速、更高容量校园网络解决方案的需求。这就是为什么25G/100G以太网解决方案正在迅速发展的原因。 什么是25G/100G以太网解决方案&#xff1f; 在25G/100G校园网络中&#xff0c;通常…

5路开关量转继电器 Modbus TCP远程I/O模块 YL95 RJ-45网络接口通信

特点&#xff1a; ● 五路开关量输入&#xff0c;五路继电器输出 ● 支持Modbus TCP 通讯协议 ● 内置网页功能&#xff0c;可以通过网页查询电平状态 ● 可以通过网页设定继电器输出状态 ● DI信号输入&#xff0c;DO输出及电源之间互相隔离 ● 宽电源供电范围&#x…

【23真题】成都理工826真题及解析!

哈喽大家好&#xff0c;现在这个时间节点&#xff0c;有很多同学开始刷真题了&#xff01;所以23真题系列正式启动&#xff01;小马哥将全面发布23真题及详细解析&#xff01; 今天分享的是23年成都理工大学826的信号与系统回忆版试题及解析。 小马哥Tips&#xff1a; 本套试…

yolov5单目测距+速度测量+目标跟踪(算法介绍和代码)

要在YOLOv5中添加测距和测速功能&#xff0c;您需要了解以下两个部分的原理&#xff1a; 单目测距算法 单目测距是使用单个摄像头来估计场景中物体的距离。常见的单目测距算法包括基于视差的方法&#xff08;如立体匹配&#xff09;和基于深度学习的方法&#xff08;如神经网…

nodejs 使用 ws/socket.io 模块 websocket 即时通讯

源码 koa-mongodb-template ws 模块 下载 npm install ws简单使用 服务端代码 const WebSocket require("ws"); const WebSocketServer WebSocket.WebSocketServer;const wss new WebSocketServer({ port: 8080 });// 监听客户端连接 wss.on("connectio…

Python Pandas 通过loc/iloc修改局部数据(第9讲)

Python Pandas 通过loc/iloc修改局部数据(第9讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ…

一款视频行为分析系统,可轻松开发安全行为检测

系列版本介绍 基于视频行为分析系统v4系列版本可以在不用考虑流媒体音视频开发&#xff0c;编解码开发&#xff0c;界面开发等情况下&#xff0c; 只需要训练自己的模型&#xff0c;开发自己的行为算法插件&#xff0c;就可以轻松开发出任何你想要的安全行为检测&#xff0c;比…

【MYSQL】--MySQL的安装以及基础

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

【Python秘技】用Python实现千图成像,千字成像,编程炫技必备!

一个千图成像&#xff0c;千字成像的程序&#xff0c;开源给大家玩玩。 用她的名字组成她的照片会不会很酷呢&#xff1f; 后续会完善更多功能&#xff0c;打包为程序。 源代码在这里&#xff1a;https://github.com/w-x-x-w/Thousand-Image-Generator 讲解在这里&#xff…

建筑模板怎么选?

在建筑领域&#xff0c;选择合适的模板材料对于确保工程质量、提高施工效率和控制成本至关重要。目前&#xff0c;常见的建筑模板主要有钢模板、塑料模板和木模板三种类型&#xff0c;每种都有其独特的优势和局限性。本文将对这些模板类型进行分析&#xff0c;并特别推荐广西生…

生物化学 荒诞医学史笔记:重金属(暂记)

“理论基础” 四液说 根据希罗多德的说法&#xff0c;古埃及人为了维持自身健康&#xff0c;每月都会使用催吐剂。希波克拉底也提倡定期呕吐。之后的好几千年中&#xff0c;这种建议不断出现。直到最近几十年&#xff0c;催吐剂还被认为是医学处方的重要组 成部分。 大…

这个食堂管理大招,再不知道就晚了!

随着社会的不断发展&#xff0c;餐饮行业也在不断创新和进步。在这个数字化时代&#xff0c;智能技术为各行各业提供了更高效、便捷的解决方案。 食堂作为人们日常生活中不可或缺的一部分&#xff0c;也迎来了智能化的时代。智慧收银系统不仅提高了食堂的运营效率&#xff0c;还…

论文Rebuttal常见格式与模板之中篇

论文Rebuttal常见格式与模板之中篇 前言5. Rebuttal可能遇到的问题5.4 实验不充分5.5 语法&#xff0c;结构&#xff0c;参考文献遗漏等问题5.6 非热点问题&#xff0c;研究意义&#xff1f; 6. 针对AC Message下篇笔记链接Rebuttal模板的好文 前言 这里承接上一篇笔记&#x…