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,一经查实,立即删除!

相关文章

Auto-GPT 学习笔记

Auto-GPT 学习笔记 Auto-GPT 简介 Auto-GPT 是一个基于 GPT-4 的自主智能体实验项目。它展示了大规模语言模型的规划、记忆和工具使用能力。Auto-GPT 的目标是实现一个完全自主的 AI 代理。GitHub 仓库 Auto-GPT 核心模块 规划(Planning) 使用强化学习策略进行多跳思考。通…

两种动态代理比较(补充),进程通信方式总结

jdk和CGLib动态代理: jdk动态代理: java提供的动态代理技术; spring aop默认采用的方式; 只能对实现了至少一个接口的类生成代理对象; CGLib动态代理: 采用底层字节码技术; 目标对象没有实现接口时采…

Nginx特性应用及载装

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

文字识别的

对于 PDF 提取文字,Tesseract OCR 是一个常用的工具。你可以使用 Tesseract OCR 的 Java API 来实现。以下是一个使用 Tesseract OCR 提取 PDF 文档文字的简单示例代码: import net.sourceforge.tess4j.Tesseract; import net.sourceforge.tess4j.Tesse…

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() {} //非静态成员函数 不…

LeetCode 1921. Eliminate Maximum Number of Monsters【贪心,计数排序】1527

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

供应链 | 顶会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;旨在解决分布式…

业绩走低,毛利率下滑,海外市场能否成为极米科技救命稻草?

撰稿|行星 来源|贝多财经 8月30日&#xff0c;成都极米科技股份有限公司&#xff08;SH:688696&#xff0c;下称“极米科技”&#xff09;发布2023年半年度业绩报告。财报显示&#xff0c;极米科技2023年上半年的业绩出现了大幅下滑&#xff0c;其中收入同比减少两成&#xf…

代码随想录二刷day06

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣242. 有效的字母异位词二、力扣349. 两个数组的交集三、力扣202. 快乐数四、力扣1两数之和 前言 一、力扣242. 有效的字母异位词 class Solution {pub…

数学建模-点评笔记 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; 牛顿莱布尼茨梯…

softmax的cuda编程详细解读——算子融合

softmax介绍 在上一篇博客我们介绍了softmax的内容以及相关的编程实现,总结一下softmax的特点如下:(没有特殊说明的情况下,考虑的仍然只是1D向量 x x x) 1:获得向量的全局最大值M 2:针对向量 x ^ = { exp ⁡ ( x i −

vue3 组件通信方式

文章目录 组件通信方式props自定义事件全局事件总线v-modeluseAttrsref与$parentprovide与injectpiniaslot 组件通信方式 props ​ 实现父子组件通信,在vue3中可以通过defineProps获取父组件传递的数据。且在组件内部不需要引入defineProps方法可以直接使用&#xff01; 父组…

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…

leetcode分类刷题:哈希表(Hash Table)(三、循环存在问题)

1、当需要快速判断某元素是否出现在序列中时&#xff0c;就要用到哈希表了。 2、本文针对的总结题型为给定的序列或需要构造的序列中是否存在循环&#xff0c;与 160. 相交链表、 141. 环形链表、142. 环形链表 II的题型一样。 202. 快乐数 这道题还考察如何对正整数求解各个位…