计算机系统应用教程网站

网站首页 > 技术文章 正文

Java线程池ThreadPoolExecutor 线程池

btikc 2024-11-21 10:55:41 技术文章 57 ℃ 0 评论

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;

经典面试题

  1. 什么时候调用线程池创建线程,什么时候可以调用,什么时候创建线程?问任务刚刚开始的时候,刚接到任务的时候,突然有线程满员的任务导致,电话刚接过来,马上就触发了线程数执行拒绝策略了。注意,拒绝有两个场景,另一个是执行问题的方法也不是满了,另外一个是在运行这个问题的时候,比如关闭的时候来了新的任务。

基础知识

  1. 实现阻尼接口的包是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

四、小池总结

做好业务处理池,分三个等级

第一等级,根据业务特性实现不同的业务流程。

第二等级,根据业务特性,动态调整线程配置。

第三等级,实时监控与配置线程池运行情况。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表