[JAVAEE] 多线程的案例(三) - 线程池

目录

一. 什么是线程池

二. 线程池的作用

 三. java提供的线程池类

 四. ThreadPoolExecutor的构造方法及参数理解

1. int corePoolSize: 核心线程数.

2. int maximumPoolSize: 最大线程数 = 核心线程数 + 非核心线程数

3. int keepAliveTime:非核心线程允许空闲的最大时间.

4. BlockingQueue workQueue: 工作队列.

5. ThreadFactory threadFactory: 工厂模式

6. RejectedExecutionHandle handle: 拒绝策略. (最重要)

五. 线程池的核心方法

六. 创建线程池的简化代码

七. 模拟实现线程池

八. 总结


一. 什么是线程池

线程池是一种并发处理机制, 它预先创建一定数量的线程, 并按照一定的策略管理和组织这些线程, 当有任务需要执行时, 线程池会从空闲线程中取出一个线程来执行任务, 执行完毕后, 这个线程又重新回到线程池中, 等待下一轮分配.


二. 线程池的作用

避免频繁的创建和销毁线程, 减少资源消耗.

那么我们为什么认为线程池会减少资源的消耗呢?

a.从线程池中获取线程, 通过程序代码即可实现, 是可控的.

b. 通过操作系统创建线程, 需要操作系统内核配合完成, 是不可控的.

c. 使用内核, 就需要一段代码切换到内核中, 这个过程会消耗资源.

因此, 使用线程池就可以减少应用程序切换到内核中的开销.


 三. java提供的线程池类

 

ThreadPoolExecutor类 继承 AbstractExecutototService抽象类.

AbstractExecutototService抽象类 实现 ExecutorService接口.

ExecutotService接口 拓展 Executor接口.


 四. ThreadPoolExecutor的构造方法及参数理解

面试题: 解释ThreadPoolExecutor类构造方法的参数分别是什么含义?

1. int corePoolSize: 核心线程数.

核心线程数就是线程池中的最少线程数, 线程池一创建, 核心线程也随之创建, 直到线程池销毁, 这些核心线程才销毁.

2. int maximumPoolSize: 最大线程数 = 核心线程数 + 非核心线程数

(非核心线程数是自适应的, 繁忙时创建, 不繁忙时销毁, 线程数不是越多越好)

3. int keepAliveTime:非核心线程允许空闲的最大时间.

(一旦非核心线程空闲的时间超过设定的时间, 它就会被优化).

TimeUnit unit: 时间单位. (枚举)

4. BlockingQueue<Runnable> workQueue: 工作队列.

(本质上也是生产者消费者模型, 调用submit就是在生产任务, 线程池中的线程就是在消费任务)

5. ThreadFactory threadFactory: 工厂模式

(也是一种设计模式, 用来弥补构造方法的缺陷)

在线程池中的作用: 设置线程池中的线程类型(核心线程/非核心线程)

6. RejectedExecutionHandle handle: 拒绝策略. (最重要)

为什么要使用拒绝策略: 队列满了, 调用submit添加任务使线程阻塞(没有真的阻塞), 这时就无法做别的事情的, 不是一个好的选择, 于是就需要使用拒绝策略. 使线程不阻塞.

AbortPolicy: 线程池直接抛出异常.

CallerRunsPolicy: 让调用submit的线程自己执行任务.

DiscardOldestPolicy: 丢弃最老的线程,  submit当前线程.

DiscardPolicy: 丢弃submit的这个任务.


五. 线程池的核心方法

submit(Runnable): 通过Runnable来描述一段任务, 使用submit将这段任务提交到线程池中, 线程池再分配空闲线程来执行这段任务.


六. 创建线程池的简化代码

ExecutorService executorService = Executors.newFixedThreadPool(4);

Executors.newFixedThreadPool(nThreads); // 最大线程数和核心线程数一样.(创建固定线程数目的线程池)

ExecutorService executorService = Executors.newCachedThreadPool();

最大线程数是一个很大的数字. (线程池中的线程数可以增加)


七. 模拟实现线程池

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;class MyThreadPool {BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(10);public MyThreadPool(int n) {// 创建固定线程数量的线程池// 创建n个线程for (int i = 0; i < n; i++) {Thread thread = new Thread(() -> {try {while (true) {Runnable runnable = blockingQueue.take();runnable.run();}} catch (InterruptedException e) {e.printStackTrace();}});thread.start();
//            System.out.println(n);}}public void submit(Runnable runnable) throws InterruptedException {blockingQueue.put(runnable);}
}
public class demo4 {static int count = 0;public static void main(String[] args) throws InterruptedException {MyThreadPool myThreadPool = new MyThreadPool(4);for (int i = 0; i < 100; i++) {myThreadPool.submit(() -> {System.out.println(Thread.currentThread().getName() + " count " + count);});}}
}

八. 总结

1. 什么是线程池. (线程池是一种并发处理机制, 它预先创建出一定数量的线程, 并使用一定的策略进行管理和组织. 当有任务需要执行时, 线程池从空闲线程出取出一个线程来执行这个任务. 执行完毕后, 这个线程又重新回到线程池中, 等待先一轮分配).

2. 线程池的作用, 避免频繁创建和销毁线程, 减少资源消耗.

(从线程池中拿取线程是应用程序级别的, 创建一个线程是操作系统内核级别的.

内核级别操作消耗的资源 > 应用程序级别消耗的资源 ==> 不可控消耗的资源 > 可控消耗的资源)

3. java提供的线程池类

4. 线程池的构造方法及参数理解. (corePoolSize, maximumPoolSize, keepAliveTime, BlockingQueue<Runnabke>, ThreadFactory, RejectedExceptionHandle)

5. 线程池的核心方法 submit(Runnable). (向线程池中提交任务, 线程池会分配空闲线程来执行).

6. 创建线程池的简化代码. (Executors.newFixedThreadPool(n) 创建具有固定线程数量的线程池

Executors.newCachedThreadPool() 创建不限制线程数量的线程池).

7. 补充: 使用shutdown方法来强制结束核心线程.

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

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

相关文章

DataX简介及使用

目录 一、DataX离线同步工具DataX3.0介绍 1.1、 DataX 3.0概览 1.2、特征 1.3、DataX3.0框架设计 1.4、支持的数据元 1.5、DataX3.0核心架构 1.6、DataX 3.0六大核心优势 1.6.1、可靠的数据质量监控 1.6.2、丰富的数据转换功能 1.6.3、精准的速度控制 1.6.4、强劲的…

正则表达式和通配符

文章目录 正则表达式和通配符的区别正则表达式&#xff08;Regex&#xff09;通配符&#xff08;Wildcards&#xff09;总结 正则表达式的概念正则表达式的由来为什么要使用正则表达式 正则表达式的语法组成修饰符元字符\f\b\B 在Linux中的基础正则和扩展正则基础正则(BRE)^$.*…

面试时被问到“Scaling Law”,该怎么答?

在大模型的研发中&#xff0c;通常会有下面一些需求&#xff1a; 计划训练一个 10B 的模型&#xff0c;想知道至少需要多大的数据&#xff1f; 收集到了 1T 的数据&#xff0c;想知道能训练一个多大的模型&#xff1f; 老板准备 1 个月后开发布会&#xff0c;给的资源是 100 …

Linux安装Nginx教程(rpm安装方式)

本章教程,主要介绍如何在Linux Centos7系统上,使用rpm的方式进行安装Nginx。 一、安装wget插件 如果不存在wget下载插件,需要安装一下。 yum install -y wget二 、下载rpm安装包 官方提供的rpm下载地址:https://nginx.org/packages/centos/7/x86_64/RPMS/ <

【Nginx系列】499错误

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Postman常见问题及解决方(全)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、网络连接问题 如果Postman无法发送请求或接收响应&#xff0c;可以尝试以下操作&#xff1a; 检查网络连接是否正常&#xff0c;包括检查网络设置、代理设置…

软考中级嵌入式系统设计师笔记分享(二)

1.TTL 电路是电流控制器件&#xff0c;而CMOS 电路是电压控制器件。 2.TTL 电路的速度快&#xff0c;传输延迟时间短(5-10ns)&#xff0c;但是功耗大。 常见的串行总线有 SPI、II2C、USB、RS232/RS422/RS485、CAN等;高速串行总线主要有 SATA、PCIE、IEEE 1394、Rapidl0、USB 3…

1.DBeaver连接hive数据库

1.hive开启远程服务&#xff0c;linux中直接输入&#xff1a;hiveserver2 2.解压dbeaver和hive-jdbc-2.1.1.zip 3.双击打开 4.数据库&#xff0c;新建连接 5.搜索hive 6.配置参数 7.编辑驱动设置 8.添加jar包 9.测试连接 10.右击&#xff0c;新建sql编辑器 11.执行sql 12.调整字…

【每日一题】LeetCode - 整数转罗马数字

在罗马数字系统中&#xff0c;七个不同的符号代表不同的值&#xff1a; 符号值I1V5X10L50C100D500M1000 罗马数字的表示方式是从最大值开始逐次减去每个符号的值&#xff0c;通过组合这些符号构建最终的表示形式。本文将介绍一个基于贪心策略的解决方案&#xff0c;将整数转换…

unity开发之Line Renderer

Line Renderer 是一个有用的工具&#xff0c;可让您在游戏中绘制线条。 它可以用作游戏的函数或调试标记。 在这里&#xff0c;让我们创建一个程序&#xff0c;根据基本用法在 Line Renderer 上移动。 目录 如何使用 Line Renderer 和基础知识 在场景中放置 Line Renderer关键组…

Catalan数 C++解决

输入描述 输入一个正整数n。 输出描述 输出Catalan数的前n项。 用例输入 1 0 用例输出 1 1 用例输入 2 5 用例输出 2 1 1 2 5 14 42 #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;int dp[n1]{0};dp[0]dp[1]1;for(int m2;…

守护头顶安全——AI高空抛物监测,让悲剧不再重演

在城市的喧嚣中&#xff0c;我们享受着高楼林立带来的便捷与繁华&#xff0c;却往往忽视了那些隐藏在高空中的危险。近日&#xff0c;震惊全国的高空抛物死刑案件被最高院核准并执行。案件中被告人多次高空抛物的举动&#xff0c;夺去了无辜者的生命&#xff0c;也让自己付出了…

Go 语言中的 for range 循环教程

在 Go 语言中&#xff0c;for range 循环是一个方便的语法结构&#xff0c;用于遍历数组、切片、映射和字符串。本教程将通过示例代码来帮助理解如何在 Go 中使用 for range 循环。 package mainimport "fmt"func main() {// 遍历切片并计算和nums : []int{2, 3, 4}…

Kafka-代码示例

一、构建开发环境 File > New > Project 选择一个最简单的模板 项目和坐标命名 配置maven路径 添加maven依赖 <dependencies><!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients --><dependency><groupId>org.apache.kaf…

深度学习 基本函数01

np.dot 是 NumPy 库中的一个函数&#xff0c;用于计算两个数组的点积&#xff08;也称为内积或数量积&#xff09;。点积是两个向量的对应元素乘积之和。 np.random.normal 是 NumPy 库中的一个函数&#xff0c;用于生成符合正态分布&#xff08;也称为高斯分布&#xff09;的…

项目管理软件中这6个小技巧帮助项目经理同时管理多个项目

在网上看到一个数据&#xff0c;只有15%的项目经理一次只需要负责一个项目&#xff0c;其他的项目经理都需要同时负责多个项目&#xff0c;甚至有15%的项目经理一次需要负责10个以上的项目。 我在工作中&#xff0c;也只有很少很少的时间里&#xff0c;是一次性只负责一个项目…

目标检测——yolov5-3.1的环境搭建和运行

第一步&#xff1a;安装anaconda环境&#xff0c;并且配置好cuda&#xff0c;安装需要的基本包 查看对应cuda版本&#xff0c;后续下载cudatoolkit需要对应版本 nvcc -V 第二步&#xff1a;创建虚拟环境&#xff0c;激活环境&#xff0c;安装所需的包 conda create -n yolo…

Visual studio 下载安装

1&#xff0c;Visual stutdio 网址 下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux 2&#xff0c;下划页面&#xff0c;点击 较早的下载 3&#xff0c;选择对应的版本进行下载

《深度学习》YOLO v1网络架构 、损失值、NMS极大值抑制

目录 一、Yolo系列v1 1、核心思想 2、示例 3、流程图解析 二、YOLO系列v1损失函数 1、位置误差 2、置信度误差 3、类别概率损失 三、NMS非极大值抑制 1、概念 2、步骤 四、YOLO v1优缺点 1、优点 1&#xff09;速度快 2&#xff09;端到端 3&#xff09;多尺度…

docker 可用镜像服务地址(2024.10.25亲测可用)

1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因&#xff1a;镜像服务器地址不可用。 2.可用地址 编辑daemon.json&#xff1a; vi /etc/docker/daemon.json内容修改如下&#xff1a; {"registry-mirrors": ["https://…