编程(41) ----------线程池

news2024/11/27 18:35:18

本篇主要提及线程池的相关内容.

依旧是从最基础的含义开始. 什么是线程池? 在计算机中池的是一个很大的概念, 分为很多种. 但无论是什么池, 其核心都是存取相关数据.

线程池也不例外, 即存放线程的池. 其存在意义与线程异曲同工. 线程产生并使用是因为进程太"重"了. 这里所说的重是其消耗的各个资源过多, 不太利于计算机的快速响应运行, 也就是说线程就可以说成是"轻量级进程". 随着时间的推移, 线程不再能满足更快速的编程, 因此又在线程的基础上有了线程池. 

其大概原理就是, 先创建若干个线程, 并放入线程池中. 随去随用, 用完放回. 这相比于单独一个个创建或者销毁线程所耗费的资源来说, 更为轻量. 为什么? 因为线程的生死大权是掌握在系统内核手上的, 而线程池获取或放回全由用户自身决定. 举个简单的例子:  

                                                                            

在超市一般都会用一个散货区, 这里的东西都是论斤卖. 也就是说, 购买流程上客户拿袋子, 装上相应所需数量的要购买的散货, 到指定地点去打包封上贴条, 最后再去收银台结账. 

假设打包这个操作是"内核态", 也就是必须要由内核操作来完成. 因此, ABC都必须将袋子交给服务员进行打包. D是属于线程池中的线程, 是属于"用户态", 所执行的是程序员自己所写的代码, 想怎么做全由自己决定. D可以选择将袋子给服务员, 但是服务员不一定会马上帮他打包, 因为已经有客户在进行等待. 同样的道理, 一个系统内核也不是只处理一个线程. 不可能来一个处理一个.

因此, 何必等待. 直接由自身控制自身打包. 能自由控制, 也能提高效率. 

在Java中也能创建线程池:

public class Main {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 50; i++) {
            int n = i;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(n);
                }
            });
        }
    }
}

这是最简单的线程池. 但这段代码中需要注意一些问题. 

首先, 在创建线程池的时候, 可以注意到相比于以往创建线程时new一个对象而言. 线程池的创建不再是单独new关键字, 而是转为了方法的一部分. 这相当于在调用该方法的时候, 也new了对象只不过将其隐藏在方法中了. 这种方法, 以及这种方法所被包含的类, 可以被称为工厂模式. 即使用普通方法来代替构造方法, 进行new对象的操作.

为何这么做? 假设有一个坐标系. 要在坐标系上构造一个点, 若是使用笛卡尔坐标系, 就得知道其x轴的值以及y轴的值. 若用极坐标表示, 就得知道其斜边以及斜边和x轴夹角的值,使用三角函数得出结论. 

                                                                             

那么现在问题来了. 假设有一个构造方法public point (double a, double). 其内部就是实现的以两个参数实现返回一个点. 请问现在这个方法内部应该调用什么? 是笛卡尔坐标的算法还是极坐标的算法? 没法确定. 因为二者所需参数相同, 返回值也相同. 而多个构造方法是通过重载来实现的. 重载有要求参数不同. 

在这种特殊情况下, 无法使用构造方法来实现. 只能考虑工厂模式在方法内部调用对应的方法实现对应的算法.

其次, 在run方法中. 注意在打印时并非是直接打印 i , 而是另建一个n再打印. 如果直接打印 i, 编译器是会报错的. 

其原因在于, 变量捕获. 首先要明确, 在这个代码中, 是有可能存在主线程for循环已经走完, 而run方法还未执行完的情况, 因为是多线程. 那在这种情况下, 就有可能 i 还来不及打印, 循环走完 i, 就被销毁了.

为避免这种情况, run方法会提前将 i 复制一份, 并在执行时创建使用, 这就是变量捕获. 但是, 变量捕获是有条件的, 在JDK1.8 以前, 条件极为苛刻. 1.8以后放松条件, 只要该变量在代码中没有被修改, 即可捕获. 因此在该代码中, i 明显是变化的, 不能进行捕获. 将其赋值n后, 不再变化, 就可以使用了.

最后, 若执行这个代码, 会发现打印出的数字是乱序的. 因为十个线程抢占式执行, 完全不会考虑顺序问题. 若代码执行完, 程序也不会自动结束, 需要手动停止. 这说明, 线程池所创建的线程全是前台线程.

                                                                         

 再来简单看一下实现线程池的类的构造方法, 以第四个为例.

corePoolSize: 核心线程数. 

maximumPoolSize: 最大线程数

可以这么理解, 核心线程数就好比是一个公司的正式员工. 而还有一类线程就相当于是临时工. 二者结合起来就是最大线程数.

keepAliveTime: 存活时间

unit: 这是上述的时间单位

这两个用于描述非核心线程的最长存在时间, 超时即销毁. 

也就是说, 当任务较多的时候. 除核心线程以外还会增加一部分临时线程进行对任务的执行. 当任务较少的时候, 就会进行销除. 但是无论怎样, 都不可能超过最大线程数. 那问题来了, 这个线程数设定多少合适? 这个其实并没有一个准确的定论. 依据不同程序特点的不同, 那么它的设置也就不同, 需要进行相应的测试才能给个大概的线程数设定.

workQueue: 线程池任务队列

要明确这个队列肯定是阻塞队列. 因为线程数量是一定的. 每个线程都从中take, 若没有任务放入队列中, 就阻塞.

threadFactory: 线程工厂, 用于创建线程.

handler: 拒绝策略, 描述若线程池任务队列满了, 继续强加任务会发生什么. 以下是四个标准库中提供的拒绝策略:

                                                                              

-----------------------------------最后编辑于2023.6.14晚上八点左右 

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

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

相关文章

Andriod开发 ViewPager PageTabStrip

1. ViewPager ViewPager常见于APP的引导页或者产品介绍&#xff0c;左右滑动展示不同页面。 ViewPager用PagerAdapter来绑定数据。PagerAdapter是个抽象类&#xff0c;所以需要写一个子类来实现它。 xml: <?xml version"1.0" encoding"utf-8"?> …

设计模式(十五):行为型之命令模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 设计模式…

I2C与I3C

Improved Inter Integrated Circuit &#xff0c;是 MIPI&#xff08;Mobile Industry Processor Interface&#xff09;移动产业处理器接口联盟推出的改进型 i2c (Inter-Integrated Circuit Bus)总线接口。 I3C Introduction I3C &#xff1a;Improved Inter Integrated Cir…

CoreDX DDS应用开发指南(10)通信状态Communication Status

13 Communication Status通信状态 DDS基础设施跟踪与数据通信相关的许多状态和统计信息。应用程序可以选择了解这些状态和统计信息中的一些、全部或全部。 每个DDS实体都有其相关状态,如表13-1所示。 一些通信状态与可用于订阅应用程序的数据相关联。这些被称为读取…

Python发展5大方向,5个对应例子让你更清晰的认知Python!

目录 前言1.数据分析相关路线&#xff1a;案例&#xff1a;使用Python进行股票数据分析 2.人工智能学习路线&#xff1a;案例&#xff1a;使用Python进行图像识别 3.Web开发学习路线&#xff1a;案例&#xff1a;使用Python和Django开发博客网站 4.科学计算学习路线&#xff1a…

(小甲鱼python)类和对象(III)总结 类的继承---构造函数、重写、钻石继承、super()函数

一、基础复习 1.类和对象&#xff08;I&#xff09;总结 类的定义、self的用法 2.类的继承(II)、类的判断isinstance()、issubclass()、多重继承、类的组合 3.类和对象&#xff08;III&#xff09;总结 类的绑定&#xff0c;self&#xff0c;__dict__的妙用 二、类的继承 1.…

4.4.2 译码器

1. 学习基础知识&#xff1a;首先&#xff0c;我会了解译码器的基本概念、原理和应用。通过阅读教科书、参考资料或在线资源&#xff0c;我会学习译码器的工作原理、不同类型的译码器以及它们在电子系统中的应用场景。 2. 研究示例和练习题&#xff1a;为了更好地理解译码器的…

12、Nginx高级之高级模块(secure_link/secure_link_md5)

一、功能 防盗链&#xff1b; ngx_http_secure_link_module模块用于检查所请求链接的真实性&#xff0c;保护资源免受未经授权的访问&#xff0c;并限制链接寿命。 该模块提供两种可选的操作模式。 第一种模式由 secure_link_secret 指令启用&#xff0c;用于检查所请求链接的真…

【Python爬虫开发基础⑤】HTML概述与基本标签详解

专栏&#xff1a;python网络爬虫从基础到实战 欢迎订阅&#xff01;近期还会不断更新~ 往期推荐&#xff1a; 【Python爬虫开发基础①】Python基础&#xff08;变量及其命名规范&#xff09; 【Python爬虫开发基础②】Python基础&#xff08;正则表达式&#xff09; 【Python爬…

出境游复苏加速,距离“回到过去”还有多远?

6月14日一早&#xff0c;日本驻华大使馆一则“自6月19日起正式签发电子签证”的消息&#xff0c;引起了旅游圈的广泛关注。尽管其电子签方案因为流程繁琐甚至超过纸质签证&#xff0c;收获了一片吐槽之声&#xff0c;但游客对出境游的期待&#xff0c;却实打实地得到了展现。 …

solr快速上手:整合SolrJ实现客户端操作(九)

0. 引言 我们前面学习了solr的服务端基础操作&#xff0c;实际项目中我们还需要在客户端调用solr&#xff0c;就像调用数据库一样&#xff0c;我们可以基于solrJ来实现对solr的客户端操作 1. SolrJ简介 SolrJ 是 Solr官方提供的 Java 客户端库&#xff0c;主要用于与 Solr 服…

【Java学习记录-8】集合

集合 特点结构Collection概述创建方式常用方法遍历方式 List概述遍历方式特有方法 特点 提供一种存储空间可变的存储类型&#xff0c;存储的数据容量可以随时发生改变 结构 Collection 概述 是单列集合的顶层接口&#xff0c;它表示一组对象&#xff0c;这些对象也称为Coll…

好用的生产型企业ERP系统有哪些?

一、好用的生产型企业ERP系统有哪些&#xff1f; 目前而言&#xff0c;制造型想要部署一款好用的ERP系统&#xff0c;通常可以从2个方向来考虑&#xff1a; 第一方向&#xff1a;传统IT软硬件。比如&#xff1a;传统ERP厂商SAP&#xff1b; 第二方向&#xff1a;与新一代数字…

基于Java人才招聘网站系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

函数参数的拓展

函数参数的默认值 C 中可以在函数声明时为参数提供一个默认值 当函数调用时没有提供默认参数的值&#xff0c;则使用默认值 参数的默认值必须在函数声明中指定 当函数声明时没有出现参数的默认值&#xff0c;而定义的时候出现参数的默认值&#xff0c;编译器会报错 当函数声…

软件测试面试题:如何测试App性能?

目录 为什么要做App性能测试&#xff1f; 怎么做App性能测试&#xff1f; 下面几款开源工具&#xff1a; APP性能测试关注哪些指标&#xff1f; 总结&#xff1a; 为什么要做App性能测试&#xff1f; 如果APP总是出现卡顿或网络延迟的情况&#xff0c;降低了用户的好感&am…

java面经 MySQL

存储引擎--MyISAM和InnoDB的区别 使用场景 对比 MySQL隔离级别--未提交读&#xff0c;提交读&#xff0c;可重复读&#xff0c;序列化 隔离级别含义 隔离级别 英文名称 含义 脏读 不可重复读 幻读 未提交读 READ UNCOMMITTED 可读取其它事务未提交的结果 √ √ √…

管理类联考——逻辑——真题篇——阅读新题型真题

阅读新题型真题 Part B-2010- Part B Directions: Read the following text and decide whether each of the statements is true or false. Choose T if the statement is true or F if the statement is not true. Mark your answers on ANSWER SHEET. (10 points) Copying…

Android——基本控件之下拉列表:Spinner(九)

1.知识点 &#xff08;1&#xff09;掌握下拉列表Spinner的使用&#xff1b; &#xff08;2&#xff09;可以通过程序配置Spinner显示内容&#xff1b; &#xff08;3&#xff09;可以通过配置文件配置Spinner显示内容。 2.具体内容 在html中&#xff0c;下拉列表使用<…

直击网络安全简史,现阶段提升免疫力是关键 | 产业安全观智库访谈

当下&#xff0c;AIGC、区块链、云计算等新兴技术发展如火如荼&#xff0c;网络安全的内涵与外延也随之出现许多变化&#xff0c;安全攻防也从早期的黑客炫技手段&#xff0c;演变为如今产业发展的底座。过去的20多年&#xff0c;网络安全行业出现了哪些新变化&#xff1f;安全…