Java 线程池概念总结(thread pool)

一、池化思想的应用

池化思想是一种常见软件设计和优化技术。以下是几个常见池化思想应用场景:

  1. 线程池:线程池是池化思想一个典型应用。通过预先创建一组线程并将它们置于就绪状态,以复用线程减少线程创建和销毁的开销,并提高系统性能和响应速度。

  2. 连接池:连接池是数据库和网络编程中常见应用。通过提前创建一批数据库连接或网络连接并将它们置于可复用状态以避免频繁创建释放连接,从而提高数据库访问和网络通信效率。

  3. 对象池:对象池用于管理和重复使用可复用的对象。例如,数据库连接池、线程安全的缓存池等。通过对象池,可以避免频繁创建和销毁对象,提高系统的性能和资源利用率。

  4. 内存池:频繁内存分配和释放可能会导致内存碎片,降低内存利用效率。内存池将一块连续内存空间划分为多个固定大小的块并维护一个空闲块列表。程序可以从内存池中申请和释放内存块以减少内存碎片和提高内存的分配性能。

  5. 字符串池:字符串池通过将相同的字符串共享在一个池中,减少内存占用和提高字符串比较的速度。Java中字符串常量池就是一种典型字符串池应用。

        这些池化思想的应用都旨在提高系统性能、资源利用率和开发效率,避免重复创建和销毁对象,从而降低系统开销,并提供更好的用户体验。

二、线程池的工作原理

线程池的工作原理可以基本分为以下几个步骤:

  1. 初始化线程池:创建线程池管理器,并设置线程池参数,包括线程数量、工作队列大小等。

  2. 创建线程:根据线程池初始配置,创建指定数量线程并将它们置于就绪状态等待执行任务。

  3. 接收任务:当有任务需要执行时线程池会接收并入队等待处理。任务可以是实现Runnable接口或Callable接口的对象。

  4. 任务调度:线程池中的线程从工作队列中获取任务,按照预设的调度策略进行选择,如先进先出(FIFO)、最近最少使用(LRU)等。

  5. 执行任务:选中的线程会从工作队列中取出任务,并执行任务的run()或call()方法。任务执行完毕后,线程进入空闲状态,等待下一个任务。

  6. 线程回收:当线程池处于空闲状态一段时间后,管理器可能会决定销毁部分线程,以节省系统资源。线程销毁后,线程池的线程数量会相应减少。

  7. 错误处理:线程池会捕获任务执行过程中产生的异常,防止线程因未捕获的异常而崩溃。异常处理策略可以根据具体需求进行自定义,如重新执行、记录日志、忽略等。

        通过上述工作原理,线程池实现了线程的复用和资源的合理利用,使得系统能够更好地处理并发任务,提高性能和响应速度。同时,线程池还能控制线程数量,避免过多的线程造成资源消耗和性能下降,提供了对线程的管理机制。

三、简述一下你对线程池的理解

       如果问到了这样的问题,可以展开说一下线程池如何用、线程池的好处、线程池的启动策略合理利用线程池能够带来三个好处。
        第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
        第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
        第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

        线程池是一种用于管理和复用线程的机制。它由一个线程池管理器、工作队列和一组线程组成。线程池管理器负责创建、销毁和监控线程池中的线程。它根据系统负载和预设条件来动态地调整线程数量,保证线程池的高效利用和合理分配。工作队列用于存储待处理的任务。线程池中的线程从工作队列中取出任务并执行。当任务数量超过线程池的处理能力时,任务会被暂时放入队列中,待有空闲线程时再进行处理。

线程是不是越多越好?

  1. 线程在java中是一个对象,更是操作系统的资源,线程创建、销毁需要时间。如果创建时间+小会时间>执行任务时间就很不合算。
  2. java对象占用堆内存,操作系统线程占用系统内存,根据jvm规范,一个线程默认最大栈大小1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多的内存。
  3. 操作系统需要频繁切换线程上下文(每个线都想被运行),影响性能。

线程池的推出,就是为了方便边的控制线程数量。

        使用线程池时,需要考虑线程数量、工作队列大小以及任务调度策略等因素,以确保线程池能够按预期工作并提供最佳的性能。同时,我们还要注意处理异常情况,避免线程由于未捕获的异常而导致整个线程池崩溃。

为什么不建议使用 Executors静态工厂构建线程池?

        阿里巴巴Java开发手册,明确指出不允许使用Executors静态工厂构建线程池,原因如下:
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险,说明:Executors返回的线程池对象的弊端如下:

1:FixedThreadPool 和 SingleThreadPool:
允许的请求队列(底层实现是LinkedBlockingQueue)长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM
2:CachedThreadPool 和 ScheduledThreadPool
允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

        创建线程池的正确姿势:避免使用Executors创建线程池,主要是避免使用其中的默认实现,那么我们可以自己直接调用ThreadPoolExecutor的构造函数来自己创建线程池。在创建的同时,给BlockQueue指定容量就可以了。

private static ExecutorService executor=newThreadPoolExecutor(10,10,60L,TimeUnit.SECONDS,new ArrayBlockingQueue(10));

或者是使用开源类库:开源类库,如apache和guava等。

线程池如何知道一个线程任务已经执行完成?

        线程池通常使用一种称为"Future"的机制来跟踪线程任务的执行状况。

        在Java中,可以通过java.util.concurrent.Future接口来表示异步计算的结果。线程池提交的任务可以返回一个Future对象,在任务执行完成后,可以通过该对象获取任务的执行结果或判断任务是否完成。

具体而言,可以按照以下步骤使用Future来知道线程任务是否已经执行完成:

  1. 提交任务:将要执行的任务提交给线程池,并获得返回的Future对象。

  2. 判断任务状态:通过调用Future的isDone()方法判断任务是否已经完成。如果任务完成,返回true;否则返回false。

  3. 获取任务结果:如果任务已经完成,可以通过调用Future的get()方法获取任务的执行结果。该方法会阻塞当前线程,直到任务完成并返回结果。

        需要注意的是,如果任务还未完成,调用get()方法会使当前线程阻塞,直到任务执行完成。如果不希望阻塞当前线程,可以使用isDone()方法轮询判断任务状态,或者使用带有超时参数的get()方法来等待一段时间后获取结果。

        总之,通过使用Future对象,线程池可以方便地跟踪和获取线程任务的执行状态和结果,从而实现对任务的管理和控制。

参考:

Java 中线程池的 7 种创建方式! - 磊哥|www.javacn.site - 博客园 (cnblogs.com)

Java线程池实现原理及其在美团业务中的实践 - 美团技术团队 (meituan.com)

JUC线程池: ThreadPoolExecutor详解 | Java 全栈知识体系 (pdai.tech)

线程池面试题 - 小魚人 - 博客园 (cnblogs.com)

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

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

相关文章

Nginx特性应用及载装

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx的网站有:网易、腾讯、阿里等。 …

MyBatis-Plus —— 初窥门径

前言 在前面的文章中荔枝梳理了MyBatis及相关的操作,作为MyBatis的增强工具,MyBatis-Plus无需再在xml中写sql语句,在这篇文章中荔枝将梳理MyBatis-Plus的基础知识并基于SpringBoot梳理MyBatis-Plus给出的两个接口:BaseMapper和ISe…

对象模型和this指针(个人学习笔记黑马学习)

1、成员变量和成员函数 #include <iostream> using namespace std; #include <string>//成员变量和成员函数分开存储class Person {int m_A;//非静态成员变量 属于类的对象上的static int m_B;//静态成员变量 不属于类的对象上void func() {} //非静态成员函数 不…

供应链 | 顶会CIKM论文精读:面向大规模三维装箱问题的数据驱动树形搜索算法

论文解读&#xff1a;丁建辉&#xff0c;李明哲&#xff0c;赵艳蓉&#xff0c;孙楚天 编者按 本次解读的文章发表于CCF-B类会议30th ACM International Conference on Information and Knowledge Management。摘要总结如下&#xff1a; 3维装箱问题&#xff08;3D-BPP&#…

Redis的缓存穿透,缓存击穿,缓存雪崩

1. 缓存穿透 什么是缓存穿透&#xff1f; 缓存穿透说简单点就是大量请求的 key 是不合理的&#xff0c;根本不存在于缓存中&#xff0c;也不存在于数据库中 。这就导致这些请求直接到了数据库上&#xff0c;根本没有经过缓存这一层&#xff0c;对数据库造成了巨大的压力&…

雪花算法生成id分析与实践

目录 1 什么是雪花算法&#xff1f; 结构 优点 缺点 2 在java中使用 使用注意&#xff1a; 测试代码 效果 1 什么是雪花算法&#xff1f; witter的雪花算法&#xff08;Snowflake Algorithm&#xff09;。雪花ID是一种分布式唯一ID生成算法&#xff0c;旨在解决分布式…

数学建模-点评笔记 9月3日

1.摘要&#xff1a;关键方法和结论&#xff08;精炼的语言&#xff09;要说明&#xff0c;方法的合理性和意义也可以说明。 评委先通过摘要筛选&#xff08;第一轮&#xff09; 2.时间序列找异常值除了3西格玛还有针对时间序列更合适寻找的方法 3.模型的优缺点要写的详细一点…

世微AP9234 升压型DC/DC LED恒流驱动

描述 AP9234是一款由基准电压源、振荡电路、误差放大电路、相位补偿电路、电流限制电路等构成的CMOS升压型DC/DC LED驱动。由于内置了低导通电阻的增强型N沟道功率MOSFET&#xff0c;因此适用于需要高效率、高输出电流的应用电路。另外&#xff0c;可通过在VSENSE端子连接电流…

754. 到达终点数字

754. 到达终点数字 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 754. 到达终点数字 https://leetcode.cn/problems/reach-a-number/description/ 完成情况&#xff1a; 解题思路&#xff1a; 牛顿莱布尼茨梯…

SWAT-MODFLOW地表水与地下水耦合

耦合模型被应用到很多科学和工程领域来改善模型的性能、效率和结果&#xff0c;SWAT作为一个地表水模型可以较好的模拟主要的水文过程&#xff0c;包括地表径流、降水、蒸发、风速、温度、渗流、侧向径流等&#xff0c;但是对于地下水部分的模拟相对粗糙&#xff0c;考虑到SWAT…

ConsoleApplication815项目(直接加载+VEH Hook Load)

上线图 ConsoleApplication815.cpp #include <iostream> #include<Windows.h> #include "detours.h" #include "detver.h" #pragma comment(lib,"detours.lib")#pragma warning(disable:4996)LPVOID Beacon_address; SIZE_T Beacon…

敏捷开发、V模型开发、瀑布模型

在软件开发领域&#xff0c;敏捷开发和V模型开发是两种主要的开发方法。它们之间的差异主要体现在开发过程的结构和组织方式上。在以下讨论中&#xff0c;我们将深入探讨这两种方法的特点和差异。 敏捷开发 敏捷开发是一种迭代和增量的软件开发方法&#xff0c;它强调灵活性和…

rz命令无法正常使用?

使用rz命令上传文件时出现如下问题&#xff1a; 这里用的是mobaxterm终端 改用xshell,secureCRT即可正常使用&#xff1a;

vscode调教配置:快捷修复和格式化代码

配置vscode快捷键&#xff0c;让你像使用idea一样使用vscode&#xff0c;我们最常用的两个功能就是格式化代码和快捷修复&#xff0c;所以这里修改一下快捷修复和格式化代码的快捷键。 在设置中&#xff0c;找到快捷键配置&#xff1a; 然后搜索&#xff1a;快捷修复 在快捷键…

Mqtt学习笔记--交叉编译移植(1)

简述 Mqtt目前在物联网行业的应用比较多&#xff0c;mqtt属于应用层的一个中间件&#xff0c;这个中间件实现消息的订阅发布机制。网上介绍Mqtt的实现原来的比较多&#xff0c;这里不细介绍。 其实在我们之前的产品中&#xff0c;自己也开发的有类似的中间件&#xff0c;除了具…

ORB-SLAM2算法12之单目初始化Initializer

文章目录 0 引言1 单目初始化Initializer1.1 构造函数1.2 成员函数1.2.1 Initialize1.2.2 FindHomography1.2.3 FindFundamental1.2.4 ReconstructH1.2.5 ReconstructF 2 总结 0 引言 ORB-SLAM2算法7详细了解了System主类和多线程、ORB-SLAM2学习笔记8详细了解了图像特征点提取…

每日一题 1921. 消灭怪物的最大数量

难度&#xff1a;中等 思路&#xff1a; 已知速度和距离&#xff0c;可求时间必定先消灭时间最短的怪物求得时间数组排序&#xff0c;只要在第 i 秒时&#xff0c;time[i] > i &#xff0c;那么就可以消灭第 i 个怪物 代码&#xff1a; class Solution:def eliminateMax…

QT(9.3)定时器,绘制事件

作业&#xff1a; 自定义一个闹钟 pro文件&#xff1a; QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecat…

PYTHON知识点学习-列表和元组

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由 Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

科目1基础知识快速入门精简

科目1-4 科目一&#xff0c;又称科目一理论考试、驾驶员理论考试。》学习道路交通安全法律、法规和相关知识学习 考试内容包括驾车理论基础、道路安全法律法规、地方性法规等相关知识&#xff0c;再加地方性法规。考试形式为上机考试&#xff0c;100道题&#xff0c;90分及以…