系列十二、线程池

一、线程池

1.1、为什么需要线程池

10年前单核CPU电脑,假的多线程,像马戏团小丑玩多个球,CPU需要来回切换。现在是多核电脑,多个线程各自跑在独立的CPU上,不用切换效率高。

1.2、优势

        线程池做的主要工作是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,那么超出数量的线程将排队等候,等其他线程执行完毕,再从队列中取出任务来执行。

1.3、主要特点

线程复用、控制最大并发数、管理线程。

(1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的销耗;

(2)提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即执行;

(3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控;

1.4、架构说明

Java中的线程池是通过Executor框架实现的,该框架中用到了Executor,Executors,ExecutorService,ThreadPoolExecutor这几个类,如下所示:

1.5、常见的线程池

1.5.1、一池N线程

适用场景:执行长期任务性能好,创建一个线程池,一池有N个固定数量的线程。

说明:newFixedThreadPool创建的线程池corePoolSize和maximumPoolSize值是相等的,它使用的是LinkedBlockingQueue

1.5.2、一池一线程

适用场景:一个任务一个任务的执行,一池一线程。

说明:newSingleThreadExecutor 创建的线程池corePoolSize和maximumPoolSize值都是1,它使用的是LinkedBlockingQueue

1.5.3、可扩容线程

适用场景:执行很多短期异步任务,线程池根据需要创建新线程,可扩容,遇强则强。

说明:newCachedThreadPool创建的线程池将corePoolSize设置为0,将maximumPoolSize设置为Integer.MAX_VALUE,它使用的是SynchronousQueue,也就是说来了任务就创建线程运行,当线程空闲超过60秒,就销毁线程。

1.6、 线程池案例

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/21 8:29* @Description: 一个银行网点有10个业务办理窗口,周末业务不繁忙开2个窗口,业务办理等待区最大能容纳20个人,模拟30个人去银行网点办理业务,使用线程池处理*/
public class ThreadPoolMainApp {public static void main(String[] args) {ExecutorService pool = new ThreadPoolExecutor(2,10,2L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(20),Executors.defaultThreadFactory(),// new ThreadPoolExecutor.AbortPolicy// new ThreadPoolExecutor.CallerRunsPolicy// new ThreadPoolExecutor.DiscardOldestPolicynew ThreadPoolExecutor.DiscardOldestPolicy());// 30个顾客请求try {for (int i = 1; i <= 30; i++) {pool.execute(() -> {System.out.println(Thread.currentThread().getName() + "\t办理业务!");});}} catch (Exception e) {e.printStackTrace();} finally {pool.shutdown();}}}

1.7、ThreadPoolExecutor的底层原理

 

1.8、线程池7大参数

1.9、线程池的底层工作原理

执行步骤:

        第一步:创建了线程池后,开始等待请求;

        第二步:当调用execute()方法添加一个请求任务时,线程池会做出如下判断:

                a、如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务;

                b、如果正在运行的线程数量大于或者等于corePoolSize,那么将这个任务放入队列

                c、如果这个时候队列满了且正在运行的线程数量还小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;

                d、如果队列满了且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会启动饱和拒绝策略来执行

        第三步:当一个线程完成任务时,它会从队列中取下一个任务来执行;

        第四步:当一个线程无事可做超过一定的时间(keepAliveTime)时,线程会判断:

                a、如果当前运行的线程数大于corePoolSize,那么这个线程就会被线程池回收;

                b、线程池的所有任务完成后,它最终会收缩到corePoolSize的大小

1.10、线程池的拒绝策略

1.10.1、概述

等待队列已经排满了,再也塞不下新任务了,同时,线程池中的max线程也达到了,无法继续为新任务服务,这个是时候我们就需要拒绝策略机制合理的处理这个问题。

1.10.2、JDK内置的拒绝策略

AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止系统正常运行。

CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。

DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加人队列中尝试再次提交当前任务。

DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种策略。

说明:以上内置拒绝策略均实现了RejectedExecutionHandle接口

1.11、工作中单一的|固定数的|可变的三种创建线程池的方法哪个用的最多(超级大坑)

答:一个都不用,我们工作中只使用自定义的。

Executors中JDK已经给你提供了,为什么不用?

1.12、工作中如何使用线程池?是否自定义过线程池

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/21 8:29* @Description: 一个银行网点有10个业务办理窗口,周末业务不繁忙开2个窗口,业务办理等待区最大能容纳20个人,模拟30个人去银行网点办理业务,使用线程池处理*/
public class ThreadPoolMainApp {public static void main(String[] args) {ExecutorService pool = new ThreadPoolExecutor(2,10,2L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(20),Executors.defaultThreadFactory(),// new ThreadPoolExecutor.AbortPolicy// new ThreadPoolExecutor.CallerRunsPolicy// new ThreadPoolExecutor.DiscardOldestPolicynew ThreadPoolExecutor.DiscardOldestPolicy());// 30个顾客请求try {for (int i = 1; i <= 30; i++) {pool.execute(() -> {System.out.println(Thread.currentThread().getName() + "\t办理业务!");});}} catch (Exception e) {e.printStackTrace();} finally {pool.shutdown();}}}

 

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

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

相关文章

GZ033 大数据应用开发赛题第07套

2023年全国职业院校技能大赛 赛题第07套 赛项名称&#xff1a; 大数据应用开发 英文名称&#xff1a; Big Data Application Development 赛项组别&#xff1a; 高等职业教育组 赛项编号&#xff1a; GZ033 …

天猫超市电商营销系统:无代码开发实现API连接集成

无代码开发实现天猫超市与电商系统的高效连接 天猫超市&#xff0c;作为天猫推出的网络零售超市&#xff0c;为广大网购消费者提供了一站式的购物服务。而通过无代码开发的方式&#xff0c;天猫超市能够实现与各种电商系统的连接和集成&#xff0c;这种方式无需进行繁琐的API开…

ESP32 http 请求

目录 参考教程1.使用的http连接2.使用Vscode-IDF创建http_request例程3.修改http_request_example_main.c函数4.已经获取到响应的数据 参考教程 ESP-IDF HTTP获取网络时间 1.使用的http连接 http://api.m.taobao.com/rest/api3.do?apimtop.common.getTimestamp请求可以得到…

【Python测试开发】:切换窗口和表单

一、多窗口切换 浏览器打开的窗口其实会有一个叫做句柄的概念。 句柄就类似于每一个标签页的ID一样&#xff0c;具有唯一性。 1.1 语法 获取当前窗口句柄&#xff0c;注意后面没有括号哦~ driver.current_window_handle获取所有窗口句柄&#xff0c;结果以列表格式存储&am…

ModBus TCP/RTU 报文解析

Modbus Tcp https://gitee.com/szwzhsz/Modbus-TCP-client-server-DotNetty.?_fromgitee_search 固定协议格式 事务标识(2byte)&#xff1a;00 00&#xff0c;可变(递增) 协议标识(2byte)&#xff1a;00 00&#xff0c;固定 长度(2byte)&#xff1a;00 06&#xff0c;可变 单…

SD3403/SS928 烧录 Uboot Kernel Rootfs是什么

Uboot : 我们知道系统上电之后&#xff0c;需要一段程序来进行初始化 。 Boot&#xff08;Universal Boot Loader&#xff09;&#xff0c;即通用Bootloader&#xff0c;是用来引导启动内核的&#xff0c;它的最终目的就是从flash中读出内核&#xff0c;放到内存&#xff08…

PySide6 Tutorials (一)表格小部件魔改

前言 Pyside6官方教程给了一个使用表格显示颜色的教程&#xff0c;原教程地址如下&#xff1a;源地址&#xff0c; 结合前面button信号的学习&#xff0c;就魔改添加了如下功能&#xff1a;增加一列按钮&#xff0c;可以修改该行的颜色值&#xff0c;通过点击按钮生成指定的颜…

深度学习之生成唐诗案例(Pytorch版)

主要思路&#xff1a; 对于唐诗生成来说&#xff0c;我们定义一个"S" 和 "E"作为开始和结束。 示例的唐诗大概有40000多首&#xff0c; 首先数据预处理&#xff0c;将唐诗加载到内存&#xff0c;生成对应的word2idx、idx2word、以及唐诗按顺序的字序列。…

万字解析设计模式之代理模式

一、代理模式 1.1概述 代理模式是一种结构型设计模式&#xff0c;它允许通过创建代理对象来控制对其他对象的访问。这种模式可以增加一些额外的逻辑来控制对原始对象的访问&#xff0c;同时还可以提供更加灵活的访问方式。 代理模式分为静态代理和动态代理两种。静态代理是在编…

【Android11】AOSPSettings增加蓝牙开关

基于Android11增加一个蓝牙开关按钮然后控制蓝牙开关 首先控制蓝牙开关的逻辑很简单&#xff0c;bluetoothAdapter.disable();就可以关闭。这里需要用到android.bluetooth.BluetoothAdapter; 1.找到蓝牙界面的xml文件加个按钮 --- a/packages/apps/Settings/res/xml/connect…

Day01 嵌入式 -----流水灯

一、简单介绍 嵌入式系统中的流水灯是一种常见的示例项目&#xff0c;通常用于演示嵌入式系统的基本功能和控制能力。流水灯由多个发光二极管&#xff08;LED&#xff09;组成&#xff0c;这些LED按照一定的顺序依次点亮和熄灭&#xff0c;形成一种像水流一样的流动效果。 二、…

单/三相dq解耦控制与特定次谐波抑制

1. 单相整流器dq坐标系下建模 单相整流器的拓扑如图所示&#xff0c;可知 u a b u s − L d i s d t − R i s {u_{ab}} {u_{s}} - L\frac{{d{i_s}}}{{dt}} - R{i_s} uab​us​−Ldtdis​​−Ris​。   将电压和电流写成dq的形式。 { u s U s m sin ⁡ ( ω t ) i s I …

选择「程序员」职业的8个理由

软件开发人员是具有创建软件程序的创意和技术技能的专业人员&#xff0c;是一个具有高回报和挑战性的职业选择。如今&#xff0c;软件开发人员几乎在每个行业工作。随着世界变得越来越数字化&#xff0c;越来越需要具有技术背景的人来创建特定的软件应用程序。 如果您考虑做一…

【React】classnames 库(可添加多个 className 类名)

文章目录 前言&#xff1a;在项目中我们有时候需要添加多个className&#xff0c;这时候就需要用到这个库了 例如&#xff1a;我们想得到这样一个效果 <div classclass1 class2></div>但是在react中&#xff0c;我们没办法像上面那样去实现&#xff0c;所以我们得…

纯JS,RSA,AES,公钥,私钥生成及加解密

通过网络找的JS源文件&#xff0c;修改后使用&#xff0c;包含RSA 密匙对生成 及AES 加解密 涉及的JS源文件 下载 GitHub - cgrlancer/RSA-AES: 纯js,RSA,AES前端加解密 前端引用 import {generateRsaKeyWithPKCS8,encryptByRSA,decryptByRSA,encrypt,decrypt,testRsa} fr…

文心一言-情感关怀之旅

如何让LLM更有温度。 应用介绍

【精选】XML技术知识点合计

XML概述 概念 XML&#xff08;Extensible Markup Language&#xff09;&#xff1a;可扩展标记语言 可扩展&#xff1a;标签都是自定义的。 发展历程 HTML和XML都是W3C&#xff08;万维网联盟&#xff09;制定的标准&#xff0c;最开始HTML的语法过于松散&#xff0c;于是W…

使用Java解决快手滑块验证码

分析页面结构&#xff1a; 使用浏览器开发者工具分析快手滑块验证码页面的HTML和JavaScript结构&#xff0c;找到滑块验证的相关元素和事件。 模拟滑块滑动&#xff1a; 使用Java的Selenium库或其他网络爬虫工具&#xff0c;模拟用户在滑块上的操作。你需要模拟鼠标点击、拖动…

企业要满足什么条件才能实施CRM系统?

CRM的作用相信大家也所有了解&#xff0c;但并不是所有的企业都适合实施CRM。或者说&#xff0c;大部分企业实施CRM并不会100%的成功。那么&#xff0c;企业实施CRM的条件是什么&#xff1f;下面我们就来说一说。 1、业务规模 如果您的客户数量较少&#xff0c;没有复杂的客户…

二分查找——34. 在排序数组中查找元素的第一个和最后一个位置

文章目录 1. 题目2. 算法原理2.1 暴力解法2.2 二分查找左端点查找右端点查找 3. 代码实现4. 二分模板 1. 题目 题目链接&#xff1a;34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 给你一个按照非递减顺序排列的整数数组 nums&#…