线程池的运行原理和使用案例

在日常开发中,如果需要使用到多线程,最简单的方式是 new Thread,但是这种方式有很大弊端:

  1. 首先new Thread 是比较消耗系统性能的,性能比较差;
  2. 线程缺乏统一的管理,会无限制的创建新线程,相互之间竞争资源或者锁,可能占用过多的资源导致系统党纪或者OOM;
  3. 缺少必要的功能,比如定时执行,线程中断,设定最长时间等功能。

 相比于直接 new Thread,java提供了四种线程池,它的好处是:

  1. 可以重用存在的线程,见面少线程对象的创建、销毁等资源的开销,性能较好;
  2. 可以统一管理线程,提高系统资源利用率,避免线程之间竞争系统资源,避免阻塞;
  3. 可以提供定时执行、并发数控制,线程中断等能力。

 Java通过Executors提供了四种线程池,分别是:

  1. newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  4. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

 但实际上,实际开发中是不允许使用上面4类线程池的,而是要求我们自定义线程池。下面我们就看下Java自带线程池的缺点。

  1. 像 newFixedThreadPool 和 SingleThreadPool 都是固定长度的线程池,一旦请求量增加,就会堆积大量的等待线程在阻塞队列,而阻塞队列的长度允许是 Integer.MAX_VALUE,很容易会造成内存溢出的问题。
  2. 像 newCachedThreadPool 和 newScheduledThreadPool 这2个线程池中允许创建的最大线程数量是 Integer.MAX_VALUE,一但请求数量增加,势必会创建大量线程,系统的性能降低,很容易出现宕机的情况。

 下面这个代码案例,是开发当中比较常用常用的一个线程池,其中核心线程数是服务器内核数的3倍,最大线程数是服务器内核数的4倍,默认的任务队列数是10000个。

public class ThreadPoolUtil {/*** 获取当前系统可用的处理器核的数量*/private static final int CORE_NUM = Runtime.getRuntime().availableProcessors();/*** 默认任务队列长度*/private static final int DEFAULT_TASK_QUEUE_SIZE = 10000;private ThreadPoolUtil() {}/*** 核心线程内核3倍,最大线程内核4倍,60等待超时销毁线程* 如果使用,线程数量需要考虑任务数量场景*/private static class ThreadPoolHolder {private static final ThreadPoolExecutor INSTANCE = new ThreadPoolExecutor(CORE_NUM * 3, CORE_NUM * 4,60, TimeUnit.SECONDS,new LinkedBlockingQueue<>(DEFAULT_TASK_QUEUE_SIZE),new ThreadFactoryBuilder().setNameFormat("OrderDispatchThreadPool-%s").build(),new ThreadPoolExecutor.CallerRunsPolicy());}public static ThreadPoolExecutor getInstance() {return ThreadPoolHolder.INSTANCE;}public static Future async(Runnable task) {return getInstance().submit(task);}public static Future async(Callable task) {return getInstance().submit(task);}public static <P> Future async(Consumer<P> method, P param) {return getInstance().submit(() -> method.accept(param));}/*** 有两个参数但是无返回值的异步执行方法, 如void noStaticFoo(Long id,Entity entity)** @param method 要执行的方法,如 , user::noStaticFoo* @param param1 第一个入参值,如id* @param param2 第二个入参值,如entity* @param <P1>   第一个入参类型* @param <P2>   第二个入参类型* @return Future对象,用以判断是否执行结束*/public static <P1, P2> Future async(BiConsumer<P1, P2> method, P1 param1, P2 param2) {return getInstance().submit(() -> method.accept(param1, param2));}/*** 单个入参,有返回值的异步执行方法 , Entity noStaticFoo(Long id)** @param method 要执行的方法,如 , user::noStaticFoo* @param param  入参值,如 id* @param <P>    入参类型,如Long* @param <R>    返回值类型,如 Entity* @return Future对象,用以判断是否执行结束、获取返回结果*/public static <P, R> Future<R> async(Function<P, R> method, P param) {return getInstance().submit(() -> method.apply(param));}/*** 两个入参,有返回值的异步执行方法 , Entity noStaticFoo(Long id)** @param method 要执行的方法,如 , user::noStaticFoo* @param param1 第一个入参值,如id* @param param2 二个入参值,如entity* @param <P1>   第一个入参类型* @param <P2>   第二个入参类型* @param <R>    返回值类型,如 Entity* @return Future对象,用以判断是否执行结束、获取返回结果*/public static <P1, P2, R> Future<R> async(BiFunction<P1, P2, R> method, P1 param1, P2 param2) {return getInstance().submit(() -> method.apply(param1, param2));}
}

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

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

相关文章

57个Linux常用命令含参数介绍和使用示例

点击下载《57个Linux常用命令含参数介绍和使用示例》 1. pwd 作用&#xff1a;显示当前所在的工作目录的全路径名称 //显示当前目录 pwd该命令无需任何参数&#xff0c;只需在终端窗口中输入 pwd 命令即可使用。 2. cd 作用&#xff1a;更改当前工作目录。 //跳转目录至D…

航空业数字化展翅高飞,开源网安专业服务保驾护航

​某知名航空公司是中国首批民营航空公司之一&#xff0c;运营国内外航线200多条&#xff0c;也是国内民航最高客座率的航空公司之一。在数字化发展中&#xff0c;该航空公司以数据驱动决策&#xff0c;通过精细化管理、数字创新和模式优化等方式&#xff0c;实现了精准营销和个…

day58算法训练|单调栈part01

参考&#xff1a;代码随想录 单调栈的使用情况&#xff1a; 通常是一维数组&#xff0c;要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置&#xff0c;此时我们就要想到可以用单调栈了。时间复杂度为O(n)。 单调栈的本质是空间换时间&#xff0c;因为在遍历…

依赖属性(Dependency Properties)和常规的 CLR 属性

在 WPF 中&#xff0c;有两种主要的属性类型可以用于数据绑定&#xff1a;依赖属性&#xff08;Dependency Properties&#xff09;和常规的 CLR 属性&#xff0c;后者通常与 INotifyPropertyChanged 接口结合使用。 依赖属性&#xff08;Dependency Properties&#xff09; …

10款值得推荐的Blazor UI组件库

前言 经常看到有小伙伴在DotNetGuide技术社区交流群里问有什么好用的Blazor UI组件库推荐的&#xff0c;本文将分享一些开源、实用、美观的Blazor UI组件库&#xff0c;提供给广大C#/.NET开发者们学习和使用&#xff08;注意&#xff1a;排名不分先后&#xff0c;都是十分优秀…

(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第2章 信息技术发展(一)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…

Python内置类属性__module__属性的使用教程

概要 在Python中&#xff0c;每个对象都有一些内置的属性&#xff0c;这些属性提供了有关对象的一些信息。其中一个内置属性是__module__属性。__module__属性是一个字符串&#xff0c;它表示定义了类或函数的模块的名称。在本篇文章中&#xff0c;我们将详细介绍__module__属…

BUUCTF——Reverse——[GXYCTF2019]luck_guy

1、题目 2、工具 Exeinfo PE&#xff1a;查壳工具。IDA&#xff1a;是一款功能强大的反汇编工具&#xff0c;用于分析和逆向工程二进制文件。python&#xff1a;编写自动化脚本。 3、方法 下载压缩包&#xff0c;解压得到一个没有后缀的文件。 用Exeinfo PE查询该文件是否加…

sql:定时执行存储过程(嵌套存储过程、使用游标)

BEGINDeclare FormNo nvarchar(20) --单号Declare Type nvarchar(50) --类型Declare PickedQty float -Declare OutQty float Declare 生产量 floatDeclare 已装箱数量 float Declare 已入库数量 floatDeclare 损耗数量 float Declare 退货品出库数量 intdeclare k c…

C++面向对象编程与泛型编程(GP)

C既支持面向对象编程&#xff0c;又支持泛型编程 1.面向对象编程 将数据结构与处理方法&#xff08;容器与算法&#xff09;组成对象封装在一个类中&#xff0c;通过类的封装隐藏内部细节&#xff0c;可以使用继承&#xff0c;多态等方法。 注意&#xff1a;list容器本身带有…

基于SpringBoot的有光摄影分享网站

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的有光摄影分享网站,java…

【计算机毕业设计】SSM实现的在线农产品商城

项目介绍 本项目分为前后台&#xff0c;且有普通用户与管理员两种角色。 用户角色包含以下功能&#xff1a; 用户登录,查看首页,按分类查看商品,查看新闻资讯,查看关于我们,查看商品详情,加入购物车,查看我的订单,提交订单,添加收获地址,支付订单等功能。 管理员角色包含以…

LiveGBS国标GB/T28181流媒体平台功能-国标级联中作为下级平台对接海康大华宇视华为政务公安内网等GB28181国标平台查看级联状态及会话

LiveGBS国标级联中作为下级平台对接海康大华宇视华为政务公安内网等GB28181国标平台查看级联状态及会话 1、GB/T28181级联是什么2、搭建GB28181国标流媒体平台3、获取上级平台接入信息3.1、如何提供信息给上级3.2、上级国标平台如何添加下级域3.2、接入LiveGBS示例 4、配置国标…

Linear Regression 线性回归

深度学习&#xff1a; 数据集模型选择训练&#xff08;KNN不需要&#xff09;推理&#xff08;预测&#xff09; 假设学生用x小时学习深度学习&#xff0c;能够得要y分数&#xff1a; 那么学习4小时&#xff0c;能够得到多少分&#xff1f; 用已知数据作为训练集&#xff1a…

Anbernic RG35XXX 固件刷入

才买的安博尼克&#xff0c;没几天发现无法开机&#xff0c;且按键失灵&#xff1b;后来发现是因为自带的存储卡坏掉的原因&#xff0c;于是决定自己买存储卡刷个系统。 参考地址&#xff1a; Anbernic RG35XX Starter Guide – Retro Game Corps Anbernic RG35XX does not …

vue2和vue3中的路由使用及传参方式

文章目录 vue2中使用路由Vue3 中使用路由路由传参方式 Vue 2 和 Vue 3 中的路由系统有很多相似之处&#xff0c;但也存在一些重要的区别。下面将分别介绍 Vue 2 和 Vue 3 中的路由使用方式&#xff0c;并了解下它们之间的不同之处。 vue2中使用路由 在 Vue 2 中&#xff0c;通…

编程语言的未来趋势:技术进步中的创新与发展

方向一&#xff1a;编程语言的发展趋势 更高级别的语言和抽象化&#xff1a;随着技术的进步&#xff0c;编程语言逐渐朝着更高级别的方向发展。这意味着语言的语法和特性将更加简洁、易于理解和使用。高级语言的出现使得开发人员能够更加专注于问题的解决&#xff0c;而不必过于…

助力数据出境安全 | 时代新威出席第二届粤港澳数据合作会议

12月19日&#xff0c;第二届粤港澳数据合作会议在广州南沙成功举办。会议以“数智力量汇聚南沙&#xff0c;打造粤港澳数据高水平合作平台&#xff0c;赋能大湾区数字经济高质量发展”为主题&#xff0c;汇聚了政府主管部门领导、粤港澳相关主管机构代表、中国工程院院士和众多…

Apollo开放平台概览 :自动驾驶的未来趋势

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 粉丝福利活动 ✅参与方式&#xff1a;通过连接报名观看课程&#xff0c;即可免费获取精美周边 ⛳️活动链接&#xf…

阿里云ESSD Entry云盘性能如何?用过的说说

阿里云服务器ESSD Entry系统盘性能怎么样&#xff1f;性能很不错&#xff0c;但不如SSD云盘和ESSD云盘&#xff0c;ESSD Entry云盘的IOPS、吞吐量不如SSD云盘和ESSD云盘。ESSD Entry系统盘是具备企业级特性及数据保护能力&#xff0c;建议在开发与测试业务和系统盘等场景中使用…