线程池是啥有啥用,怎么用,如何自己实现一个

news2024/9/21 21:52:25

目录

一、线程池是啥,有啥用

二、线程池怎么用 

1.构造方法 

2.如何使用Java的线程池  

三、简单实现一个线程池


假设我是一个(好看+有才华) 的妹子,那么我就会有很多追求者,这些也叫备胎们,我们若把他们放到一个地方,那就叫“备胎池”。同理,线程就叫“线程池”。

一、线程池是啥,有啥用

频繁的创建销毁线程开销太大,所以我们会先创建一些线程放着,要用的时候直接拿就行了,这些线程都放一块地方,用完之后再放回这个地方,那么我们管这个地方叫“线程池”。

 所以:线程池最⼤的好处就是减少每次启动、销毁线程的损耗。

 

那么为什么线程池的效率更高,开销更小呢? 

 那么就得谈谈:用户态和内核态

比如说:

1)在银行你要办业务,可能会需要身份证或者户口本复印件,这时候,你如果没带,那么银行可能会有复印机。

2)那么你有2种选择:第一种是去柜台让柜员帮你,第二种是自己去大厅的复印机复印。

3)内核态:如果让柜员帮你去后台复印,可能没这么快,柜员也许要帮别人也复印,也可能去摸鱼,也可能去上个厕所。我们知道操作系统是由内核和软件组成,有很多软件都需要内核管理,可能会没那么及时。

4)用户态:如果你是自己去大厅复印,自给自足,非常的快。

5)而我们的线程池就是用户态,自己创建线程是内核态,所以效率会比线程池低。

二、线程池怎么用 

 我们有专门的类表示线程池:ThreadPoolExecutor

1.构造方法 

下面是它的构造方法,最主要的是第4个最为全面,其他三个都是从第4个演化出来的。

 我们分析一下这个线程池的参数:

  • corePoolSize:正式员⼯的数量. (正式员⼯, ⼀旦录⽤, 永不辞退)
  • maximumPoolSize: 正式员⼯ + 临时⼯的数⽬. (临时⼯: ⼀段时间不⼲活, 就被辞退)
  • keepAliveTime: 临时⼯允许的空闲时间
  • unit: keepaliveTime 的时间单位, 是秒, 分钟, 还是其他值
  • workQueue: 传递任务的阻塞队列
  • threadFactory: 创建线程的⼯⼚, 参与具体的创建线程⼯作,通过不同线程⼯⼚创建出的线程相当于 对⼀些属性进⾏了不同的初始化设置
  • RejectedExecutionHandler: 拒绝策略, 如果任务量超出公司的负荷了接下来怎么处理 
    1. AbortPolicy(): 超过负荷, 直接抛出异常          
    2. CallerRunsPolicy(): 调⽤者负责处理多出来的任务     
    3. DiscardOldestPolicy(): 丢弃队列中最⽼的任务
    4. DiscardPolicy(): 丢弃新来的任务  

1)corePoolSize和maximumPoolSize中,如果核心线程数是M个,在使用的过程中发现不够用,会自动扩容多M个,直至最大线程数max个。

 2)keepAliveTime和unit是姐妹,一起用的,就是实习生(非核心线程)太久没活干了,就会裁掉它,怎么样才算太久呢?就需要你自己设置一个时间

3)workQueue是我们需要传进去的堵塞队列,线程池就是一个生产者消费者模型,程序员把任务submit放进线程池中。这个队列可以自己设计容量和类型。

4)线程工厂,是为了弥补构造方法的不足,比如假设我在二维中需要表示一个点,我有2种方法,第一种是横纵坐标,第二种是用极坐标,

但是这样的话重载就失效了,因为名字参数什么的啥都一样啊,构成不了重载。

而是需要工厂设计模式解决,如上图。

5)拒绝策略(重点):当线程池的要执行的任务满了,它就会进行堵塞。但是有时候这未必是件好事。比如说你女神直接拒绝你,比起干耗着你好,这样你就能开启新的生活了。

假设线程池是女神,你是任务,但是备胎太多了忙不过来。

第一个就是女神拒绝了你,你崩溃了,其他备胎也崩溃了(没想到女神有这么多备胎);

第二个女神不想你追她,让你去追其他小姐姐,但是女神依旧和备胎们约会;

第三个是把追的最久的备胎扔掉,没新鲜感了,和最新追我的约会;

第四个是把最新的备胎踢掉,是个念旧的女神,就当一切没有发生,继续和之前的备胎们约会。

2.如何使用Java的线程池  

虽然ThreadPoolExecutor固然强大,但是参数太多,用起来确实麻烦,所以Java标准库中有更方便的:Executor提供了一些工厂方法,比如:

接受线程池的类型:ExecutorService

创建便捷线程池的方法:newFixedThreadPool(),把核心线程数和最大线程数设置成一样,不会自动扩容

添加任务到线程池执行:submit() 

public static void main(String[] args) throws InterruptedException {
        ExecutorService service=Executors.newFixedThreadPool(4);
        for(int i=0;i<100;i++){
            int id=i;
        service.submit(()->{
            Thread current=Thread.currentThread();
            System.out.println("hello world "+id+ " "+current.getName());
        });

        }
        Thread.sleep(2000);
        service.shutdown();
        System.out.println("程序结束");
    }

三、简单实现一个线程池

需要如下条件:

一个堵塞队列queue,来装要执行的任务,通过take取任务。

线程池类,来用for循环放线程(相当于线程池),这个类有submit()方法用queue队列中用put就能放进去执行这些线程中。

(由于拒绝策略太麻烦了,这里没有写出来,感兴趣的可以自行写一下)

class MyThreadPool {
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    //创造线程
    public MyThreadPool(int n) {
        for (int i = 0; i < n; i++) {
            Thread t = new Thread(() -> {
                while (true) {
                    try {
                        Runnable runnable=queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    }

    //创建任务
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }
}

public class demo15 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPool myThreadPool=new MyThreadPool(4);
        for(int i=0;i<1000;i++){
            int id=i;
            myThreadPool.submit(()->{
                System.out.println("执行任务 "+id+" "+Thread.currentThread().getName());
            });
        }
    }

}
  •  核⼼操作为 submit,将任务加⼊线程池中
  •  使⽤ Worker 类描述⼀个⼯作线程。使⽤ Runnable 描述⼀个任务.
  •  使⽤⼀个 BlockingQueue 组织所有的任务
  •  每个 worker 线程要做的事情:不停的从 BlockingQueue 中取任务并执⾏
  •  指定⼀下线程池中的最⼤线程数 maxWorkerCount;当当前线程数超过这个最⼤值时,就不再新增线程了

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

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

相关文章

71、哪吒开发板试用结合oak深度相机进行评测

基本思想:收到intel的开发板-小挪吒,正好手中也有oak相机,反正都是openvino一套玩意,进行评测一下,竟然默认是个window系统,哈哈

STL-vector练习题

118. 杨辉三角 思路&#xff1a; 杨辉三角有以下性质使我们要用到的&#xff1a; ● 每行数字左右对称&#xff0c;由 1 开始逐渐变大再变小&#xff0c;并最终回到 1。 ● 第 n 行&#xff08;从 0 开始编号&#xff09;的数字有 n1 项&#xff0c;前 n 行共有 2n(n1)个数。…

linux重要文件

/etc/sysconfig/network-scripts/ifcfg-eth1 网卡重启 /etc/init.d/network restart ifup ethname & ifdown ethname /etc/resolv.conf 设置Linux本地的客户端DNS的配置文件 linux客户端DNS可以在网卡配置文件(/etc/sysconfig/network/ifcfg-eth0 DNS2)里配置 也可以在/et…

SSY20240916提高组T1题解__贪心+大模拟

题面 题面描述 fe和xt在玩一个游戏, 在 n m n\times m nm的网格图上进行. 定义 ( a , b ) , ( c , d ) (a,b)\;,\;(c,d) (a,b),(c,d)见距离为 ∣ a − c ∣ ∣ b − d ∣ |a-c||b-d| ∣a−c∣∣b−d∣ 现在游戏按照以下步骤进行: xt选择 k k k个格子fe选择一个格子(不能选…

QT + WebAssembly + Vue环境搭建

Qt6.7.2安装工具 emsdk安装 git clone https://github.com/emscripten-core/emsdk.git cd emsdk emsdk install 3.1.50 emsdk activate 3.1.50 Qt Creator配置emsdk 效果 参考 GitHub - BrockReece/vue-wasm: Vue web assembly loader Emscripten cmake多版本编译-CSDN博客 …

【数据结构】排序算法---希尔排序

文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 1. 定义 希尔排序&#xff08;英语&#xff1a;Shell sort&#xff09;&#xff0c;也称为缩小增量排序法&#xff0c;是[直接插入排序]的一种改进版本。希尔排序以它的发明者希…

优化最长上升子序列

前言&#xff1a;平时我们做的题目都是用动态规划做的&#xff0c;但是有没有能够优化一下呢&#xff1f; 有一个结论&#xff0c;长度为 i 的一个序列&#xff0c;最后一个元素一定是构成长度为 i 的序列中最小的 我们可以用二分来优化 题目地址 #include<bits/stdc.h>…

【设计模式】创建型模式(四):建造者模式

创建型模式&#xff08;四&#xff09;&#xff1a;建造者模式 1.概念2.案例3.优化 1.概念 建造者模式 是一种创建型设计模式&#xff0c;它允许你创建复杂对象的步骤与表示方式相分离。 建造者模式是一种创建型设计模式&#xff0c;它的主要目的是将一个复杂对象的 构建过程…

极速上云2.0范式:一键智连阿里云

在传统上云的现状与挑战&#xff1a; 专线上云太重&#xff0c;VPN上云不稳&#xff0c;云上VPC&#xff0c;云下物理网络&#xff0c;多段最后一公里...... 层层对接&#xff0c;跳跳延迟&#xff0c;好生复杂! 当你试图理解SD-WAN供应商和阿里云的文档&#xff0c;以协调路由…

7-ZIP工具的功能分享:合并分卷压缩文件

在日常工作中&#xff0c;有些大文件无法单独传输&#xff0c;我们通常会通过压缩拆分成多个分卷文件来完成传输。 当完成传输后&#xff0c;不想要这么多分卷文件的时候&#xff0c;就可以通过7-ZIP工具的合并功能来解决这个问题。下面一起来看看&#xff0c;具体如何操作。 …

【C++算法】位运算

位运算基础知识 1.基础运算符 << : 左移 >> : 右移 ~ : 取反 & : 按位与&#xff0c;有0就是0 I : 按位或&#xff0c;有1就是1 ^ : 按位异或&#xff0c;&#xff08;1&#xff09;相同为0&#xff0c;相异为1&#xff08;2&#xff09;无进位相加 2.…

【docker】阿里云使用docker,2024各种采坑

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ dial tcp: lookup on 8.8.8.8:53: no such host失败属于DNS问题 2️⃣ docker镜像配置配置最新镜像源 3️⃣ 【重点】阿里云专用获取自己的镜像加速器地址配置镜像地址 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x…

MySQL_SQLYog简介、下载及安装(超详细)

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

如何设置xshell关闭最后一个选项卡标签时不退出软件?

不知道你是否遇到这个问题&#xff0c;就是在使用xshell的时候&#xff0c;每次关闭最后一个选项卡标签的时候&#xff0c;xshell软件默认就退出了&#xff0c;好多次我都只是想要关闭&#xff0c;而非退出&#xff0c;所以该如何设置&#xff0c;才能到我们的预期的效果呢&…

re题(23)BUUFCTF-[FlareOn4]login

BUUCTF在线评测 (buuoj.cn) 下载后打开看到是一个txt和一个html 分别打开看看&#xff0c;txt是提示&#xff0c;html应该就是要破解的网页 打开网页&#xff0c;查看源代码 找到程序&#xff0c;变灰的部分是关键&#xff0c;是指如果是前13个字母就加13&#xff0c;如果是…

手机端跑大模型:Ollma/llama.cpp/vLLM 实测对比

昨天给大家分享了&#xff1a;如何在手机端用 Ollama 跑大模型 有小伙伴问&#xff1a;为啥要选择 Ollama&#xff1f; 不用 Ollama&#xff0c;还能用啥&#xff1f;据猴哥所知&#xff0c;当前大模型加速的主流工具有&#xff1a;Ollama、vLLM、llama.cpp 等。 那我到底该…

鸿蒙版 React Native 正式开源,ohos_react_native 了解一下

距离鸿蒙 Next 宣布一年后&#xff0c;除了 Flutter 的鸿蒙支持之外&#xff0c;React Native 的社区支持的 ohos_react_native 也终于在 OpenHarmony-SIG 对外开源&#xff0c;并且和 Flutter 不同在于&#xff0c;本次开源的版本是基于 React Native 0.72.5 。 ohos_react_n…

算法——贡献法

前天的AtCoder Beginner Contest 371 D题碰到了这个贡献法&#xff0c;刚好之前的第十一届蓝桥杯省赛第二场真题AcWing 2868. 子串分值也是用的这个方法hh,但是赛时没有搞出来。。。 AcWing 2868. 子串分值 对于一个字符串 SS&#xff0c;我们定义 SS 的分值 f(S)f(S) 为 SS 中…

UDS 诊断 - TransferData(传输数据)(0x36)服务

UDS 诊断服务系列文章目录 诊断和通信管理功能单元 UDS 诊断 - DiagnosticSessionControl&#xff08;诊断会话控制&#xff09;&#xff08;0x10&#xff09;服务 UDS 诊断 - ECUReset&#xff08;ECU重置&#xff09;&#xff08;0x11&#xff09;服务 UDS 诊断 - SecurityA…

芯片制造过程(科普版)

tip&#xff1a;是搬运过来的&#xff0c;vx公众号&#xff1a;胖虎说可科普(感觉它的视频也是不知道哪里搞过来的&#xff0c;bushi) 目录 1 芯片结构2 制造过程2.1 晶圆的制造2.2 晶圆的加工2.3 掩膜电路2.4 光刻2.5 离子注入2.6 切割 封装等 最后 记录一下编写过程&#xff…