网站首页 > 技术文章 正文
1.什么是业务线程池?
在业务开发中,使用处理业务的线程池。
2.为什么需要流水池?
例如,对于同一个人的逻辑逻辑业务开发的,的操作不一定是同时进行的。进行(对事务性的严格要求)或者是对数据的业务操作这些;都是可以异步进行的。需要开发者根据实际的场景去灵活应用,达到的响应,最大的业务效果。
3. 业务池应用的思路是来自哪里?
个人理解,来自开源框架。虽然他们是线程池,但请稍候,对于请求请求响应的所有请求,我们都需要主动提出请求,我们需要处理所有的请求业务逻辑的处理,因此,业务线程池,框架池,然后并没有什么区别。
一、业务处理池的好处
这里借用《Java 扩展程序的艺术》提到的 使用一下线程池的好处 :
- 资源 占用。
- 提高响应速度 。当任务到达时,任务可以不需要等到线程创建就立即执行。
- 线程 是稀缺资源,无限制地创建,然后会系统资源,降低系统的持续时间,使用线程池可以进行统一的分配,优和。
二、认识池底
参数说明
/**
* 用给定的最初的参数创建一个新的线程执行器。
*/
public ThreadoolPool ( , //线程池的核心线程 int maximumPoolSize , // 线程池的最大线程数long keepAliveTime , //线程池的最大线程数时,多余的线程数当的最长时间TimeUnit ,一般时间单位BlockingQueue < Runnable > workQueue, //任务调度,使用等待执行任务的请求, //线程工厂线程工厂线程工厂,用于创建线程,默认可以处理RejectExecutionHandler handler //策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务) {
if ( corePoolSize
< 0 ||
最大池大小<= 0 ||
最大池大小<核心池大小||
keepAliveTime < 0 )
throw new IllegalArgumentException ( ) ;
if ( workQueue == null || threadFactory == null || handler == null )
throw new NullPointerException ( ) ;
这个。核心池大小=核心池大小;
这个。最大池大小=最大池大小;
这个。工作队列=工作队列;
这个。keepAliveTime =单位。toNanos ( keepAliveTime ) ;
这个。线程工厂=线程工厂;
这个。处理程序=处理程序;
}
拒绝策略
- AbortPolicy:直接抛出异常,这是默认策略;
- CallerRunsPolicy:用调用者但是处理的线程来执行任务;(这种情况下,可以保证数据不遗失,会阻止主线程)
- DiscardOldestPolicy:当前执行丢弃任务;拒绝中考最前的,并
- DiscardPolicy:直接丢弃任务;
Executor中的shutdown()、shutdownNow()、Termination()的含义和区别
- shutdown():停止接收新任务,原来的任务继续执行
- shutdownNow():停止接收新任务,原来的任务停止执行
- awaitTermination(long timeOut, TimeUnit unit):当前阻塞
注意:
awaitTermination 是一般用于关机使用的。
参考文章
https://blog.csdn.net/xiaojin21cen/article/details/81778651
ThreadPoolExecutor 运行状态
ThreadPoolExecutor类中定义了5个整数性质,状态分别为
// runState 存储在高位
private static final int RUNNING = - 1 << COUNT_BITS;
私有 静态 最终 int SHUTDOWN = 0 << COUNT_BITS;
私有 静态 最终 int STOP = 1 << COUNT_BITS;
私有 静态 最终 int整理 = 2 << COUNT_BITS;
私有 静态 最终 int终止 = 3 << COUNT_BITS;
经典面试题
- 什么时候调用线程池创建线程,什么时候可以调用,什么时候创建线程?问任务刚刚开始的时候,刚接到任务的时候,突然有线程满员的任务导致,电话刚接过来,马上就触发了线程数执行拒绝策略了。注意,拒绝有两个场景,另一个是执行问题的方法也不是满了,另外一个是在运行这个问题的时候,比如关闭的时候来了新的任务。
基础知识
- 实现阻尼接口的包是BlockingQueue,jdk1.5新增的,在juc,作者是Lea,它的父接口是Queue,也是jdk1.5新增的,在java.util下面的包,属于集合类,作者还是道格·李。
三、最佳解决方案
1.非常喜欢线程池的状态,关注线程运行情况(个人)
/**
* 打印线程池的状态
*
* @param threadPool 线程池对象
*/
public static void printThreadPoolStatus ( ThreadPoolExecutor threadPool ) {
ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor ( 1 , createThreadFactory ( "print-thread-pool-status" , false ) ) ;
预定的执行器服务。scheduleAtFixedRate ( ( ) -> {
log .info ( " =========================" ) ;
日志。info ( "线程池大小:[{} ] ",线程池。getPoolSize ( ) ) ;
日志。info ( "活动线程:{ } " , threadPool.getActiveCount ( ) ) ;
日志。info ( "任务数:{ } " , threadPool.getCompletedTaskCount ( ) ) ;
日志。信息(“队列中的任务数:{}”,线程池。获取队列()。大小( ) ) ;
日志。信息(“============================”);} , 0 , 1 ,时间单位。秒);}
2.不同业务使用不同的业务流程池
父子任务也不要使用一个线程池(死锁),死因:父子任务任务在等待父任务完成任务,等待父任务释放核心线程,父线程线程池。
3.为什么不能使用罂粟的执行者工具创建线程池
拒绝拒绝,所有的电话都没有问题。
4.如果解决问题?
有一个简单且适用面比较广的公式:
- CPU密集型任务(N+1):这个 任务类型的主要消耗是CPU,可以将线程数为N(CPU核心数)+1,比CPU核心数多出来的一个线程是为了阻止线程偶发的使用页中断,其他原因的任务而带来的影响,CPU 运行或暂停运行状态。而在这种情况下出现的一个线程就可以充分利用 CPU 暂停的时间。
- I/O密集型任务(2N个 任务应用起来,用一些时间来处理I/O应用,不会在系统内使用而线程在处理段处理)因此就可以将 CPU 交出给其他线程使用。在 I/O 密集型任务的应用中,我们可以多配置一些线程,具体的计算方法是 2N。
5.[美团]Java线程池实现原理以及在美团业务中的实践
- 时间安排过长,有最大数量的线程处理请求数量增加,大量任务在中,导致任务执行时间过长,导致服务器的大量任务失败。
- ThreadPool 的corePoolSize 的值是可以设置的。利用这点加上配置中心,可以动态的调整核心线程数。
参考文章:
- https://mp.weixin.qq.com/s?__biz=Mzg3NjU3NTkwMQ==&mid=2247505103&idx=1&sn=a041dbec689cec4f1bbc99220baa7219&source=41#wechat_redirect
- https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html
四、小池总结
做好业务处理池,分三个等级
第一等级,根据业务特性实现不同的业务流程。
第二等级,根据业务特性,动态调整线程配置。
第三等级,实时监控与配置线程池运行情况。
- 上一篇: 8 个线程池的深渊巨坑,使用不当直接生产事故!!!
- 下一篇: 心跳与超时:高并发高性能的时间轮超时器
猜你喜欢
- 2024-11-21 Java 线程池 | ThreadPoolExecutor 原理分析
- 2024-11-21 面试侃集合 | DelayQueue篇
- 2024-11-21 springboot-如何配置线程池实现定时任务
- 2024-11-21 ThreadPoolExecutor源码解析
- 2024-11-21 心跳与超时:高并发高性能的时间轮超时器
- 2024-11-21 8 个线程池的深渊巨坑,使用不当直接生产事故!!!
- 2024-11-21 java线程池核心类ThreadPoolExecutor的应用
- 2024-11-21 Java线程池:ExecutorService 开发入门
- 2024-11-21 面试官:你给我说一下什么是时间轮吧?
- 2024-11-21 定时任务实现的关键DelayQueue延迟队列
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)