`
xiaofengxbf
  • 浏览: 19109 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

ThreadPoolExecutor使用情况

    博客分类:
  • java
 
阅读更多

整个ThreadPoolExecutor的任务处理有4步操作:

 

  • 第一步,初始的poolSize < corePoolSize,提交的runnable任务,会直接做为new一个Thread的参数,立马执行
  • 第二步,当提交的任务数超过了corePoolSize,就进入了第二步操作。会将当前的runable提交到一个block queue中
  • 第三步,如果block queue是个有界队列,当队列满了之后就进入了第三步。如果poolSize < maximumPoolsize时,会尝试new 一个Thread的进行救急处理,立马执行对应的runnable任务
  • 第四步,如果第三步救急方案也无法处理了,就会走到第四步执行reject操作。
几点说明:(相信这些网上一搜一大把,我这里简单介绍下,为后面做一下铺垫)
  • block queue有以下几种实现:
    1. ArrayBlockingQueue :  有界的数组队列
    2. LinkedBlockingQueue : 可支持有界/无界的队列,使用链表实现
    3. PriorityBlockingQueue : 优先队列,可以针对任务排序
    4. SynchronousQueue : 队列长度为1的队列,和Array有点区别就是:client thread提交到block queue会是一个阻塞过程,直到有一个worker thread连接上来poll task。
  • RejectExecutionHandler是针对任务无法处理时的一些自保护处理:
  • 容易被人忽略的点:
    1.  pool threads启动后,以后的任务获取都会通过block queue中,获取堆积的runnable task.
     
    所以建议: block size >= corePoolSize ,不然线程池就没任何意义
    2.  corePoolSize 和 maximumPoolSize的区别, 和大家正常理解的数据库连接池不太一样。
      *  据dbcp pool为例,会有minIdle , maxActive配置。minIdle代表是常驻内存中的threads数量,maxActive代表是工作的最大线程数。
      *  这里的corePoolSize就是连接池的maxActive的概念,它没有minIdle的概念(每个线程可以设置keepAliveTime,超 过多少时间多有任务后销毁线程,默认只会针对maximumPoolSize参数的线程生效,可以设置 allowCoreThreadTimeOut=true,就可以对corePoolSize进行idle回收)。 
      * 这里的maximumPoolSize,是一种救急措施的第一层。当threadPoolExecutor的工作threads存在满负荷,并且 block queue队列也满了,这时代表接近崩溃边缘。这时允许临时起一批threads,用来处理runnable,处理完后通过keepAliveTime进 行调度回收。
     
    所以建议:  maximumPoolSize >= corePoolSize =期望的最大线程数。 (我曾经配置了corePoolSize=1, maximumPoolSize=20, blockqueue为无界队列,最后就成了单线程工作的pool。典型的配置错误)
     
    3. 善用blockqueue和reject组合. 这里要重点推荐下CallsRun的Rejected Handler,从字面意思就是让调用者自己来运行。
    我们经常会在线上使用一些线程池做异步处理,比如我前面做的(业务层)异步并行加载技术分析和设计将 原本串行的请求都变为了并行操作,但过多的并行会增加系统的负载(比如软中断,上下文切换)。所以肯定需要对线程池做一个size限制。但是为了引入异步 操作后,避免因在block queue的等待时间过长,所以需要在队列满的时,执行一个callsRun的策略,并行的操作又转为一个串行处理,这样就可以保证尽量少的延迟影响。
     
    所以建议: RejectExecutionHandler = CallsRun ,  blockqueue size = 2 * poolSize (为啥是2倍poolSize,主要一个考虑就是瞬间高峰处理,允许一个thread等待一个runnable任务)

  • 1. Reject 直接抛出Reject exception
    2. Discard 直接忽略该runnable,不可取
    3. DiscardOldest 丢弃最早入队列的的任务
    4. CallsRun 直接让原先的client thread做为worker线程,进行执行
分享到:
评论

相关推荐

    线程池ThreadPoolExecutor使用简介与方法实例

    线程池ThreadPoolExecutor使用简介与方法实例 线程池ThreadPoolExecutor是Java并发编程中一个非常重要的概念,它允许开发者将任务提交给线程池,并由线程池来管理这些任务的执行。今天,我们将对线程池...

    ThreadPoolExecutor线程池的使用方法

    ThreadPoolExecutor线程池的使用方法 ThreadPoolExecutor线程池是Java提供的开发框架,管理线程的创建、销毁、优化、监控等。它提供了四种不同的任务队列:ArrayBlockingQueue、LinkedBlockingQueue、...

    使用线程池ThreadPoolExecutor 抓取论坛帖子列表

    本文将详细讲解如何使用Java中的`ThreadPoolExecutor`来抓取论坛帖子列表,结合源码分析和实用工具的应用。 首先,我们要了解线程池的基本原理。线程池是由一组预先创建的线程组成的,这些线程可以复用,而不是每次...

    ThreadPoolExecutor运转机制介绍

    非核心线程在没有任务执行的情况下等待新任务的最大时间。超过这个时间后,非核心线程会被终止。 - **unit**:与 `keepAliveTime` 相关联的时间单位。 - **workQueue**:用于存放等待执行的任务的阻塞队列。如果所有...

    spring线程池ThreadPoolExecutor配置以及FutureTask的使用

    这个类是Spring对Java内置的`java.util.concurrent.ThreadPoolExecutor`的封装,允许开发者在Spring应用上下文中声明式地定义线程池。在本篇文章中,我们将深入探讨`ThreadPoolTaskExecutor`的配置及其使用,并结合`...

    Spring线程池ThreadPoolExecutor配置并且得到任务执行的结果

    在使用ThreadPoolExecutor执行任务时,我们可以使用FutureTask来获取任务执行结果。FutureTask是一个实现了Runnable和Future接口的类,它可以帮助我们获取任务执行结果。例如,我们可以创建一个FutureTask对象,并将...

    线程池ThreadPoolExecutor原理源码分析.md

    线程池作为 Java 并发编程中的重要组件,在实际应用中被广泛使用。其核心类 `ThreadPoolExecutor` 实现了对线程的管理、调度等功能。本文将围绕 `ThreadPoolExecutor` 的核心方法 `execute()` 进行深入解析,帮助...

    说说你对ThreadPoolExecutor的理解.docx

    ThreadPoolExecutor是Java并发编程中非常重要的一个组件,它位于`java.util.concurrent`包下,用于管理线程资源,实现线程池服务。...理解和熟练使用ThreadPoolExecutor对于编写高性能的多线程Java程序至关重要。

    11-线程池ThreadPoolExecutor底层原理源码分析(上)-周瑜.pdf

    根据提供的文件信息,我们可以深入探讨线程池`ThreadPoolExecutor`的工作原理及其实现细节,同时也会涉及并发编程中的一些关键概念和技术。 ### 线程池`ThreadPoolExecutor`概述 `ThreadPoolExecutor`是Java中非常...

    java 中ThreadPoolExecutor原理分析

    在 Java 中,线程池是使用 ThreadPoolExecutor 实现的,它提供了一个线程池管理器,可以根据需要创建、管理和销毁线程。 ThreadPoolExecutor 的构造函数参数包括 corePoolSize、maximumPoolSize、keepAliveTime、...

    Django如何使用asyncio协程和ThreadPoolExecutor多线程

    在Django框架中,使用`asyncio`协程和`ThreadPoolExecutor`多线程可以显著提升处理I/O密集型任务的效率。这是因为协程能够利用异步编程模型,避免不必要的阻塞,而多线程则允许同时处理多个任务。下面我们将深入探讨...

    java线程池使用后到底要关闭吗

    在这两种情况下,使用线程池可以帮助开发者更好地管理线程资源,提高系统的性能和可靠性。 然而,在使用java线程池时,一个常见的问题是:使用完线程池后到底要不要关闭?如果不关闭线程池,可能会导致内存泄露和...

    在spring boot中使用java线程池ExecutorService的讲解

    在 Spring Boot 中使用 Java 线程池 ExecutorService 的讲解 Spring Boot 作为一个流行的 Java 框架,提供了许多便捷的功能来帮助开发者快速...通过配置线程池的核心参数,我们可以根据实际情况来调整线程池的性能。

    Java分布式应用学习笔记07线程池应用

    4. **提供缓冲队列**:当请求的数量超过线程池中可用线程的数量时,线程池会将请求放入一个缓冲队列中等待执行,从而避免了立即拒绝或阻塞新任务的情况。 #### Java线程池实现 在Java中,`java.util.concurrent....

    05.抓取北京新发地菜价1

    知识点1: 并发编程 - 使用ThreadPoolExecutor实现多线程下载 在上述代码中,我们使用了`concurrent.futures`模块的`ThreadPoolExecutor`类来实现多线程下载。`ThreadPoolExecutor`是一个高级别的并发编程工具,它...

    Tomcat线程池实现简介

    线程池是一种多线程管理技术,它可以有效地控制运行的线程数量,避免过多的线程导致资源浪费,同时确保在高并发情况下系统的稳定性和响应速度。 Tomcat提供了两种线程池实现,一种是基于Apache Portable Runtime ...

    python concurrent.futures 中文文档

    在使用ThreadPoolExecutor时,需要注意可能发生的死锁情况。例如,如果一个函数调用在等待另一个函数调用的结果,而这个另一个函数调用又在等待第一个函数调用的结果,那么就会形成死锁。为了避免这种情况,应当注意...

    java Fork Join框架及使用

    与之相比,ForkJoinPool的一个不同之处在于,它为每个线程提供了独立的工作队列,而ThreadPoolExecutor则使用共享的工作队列。 ForkJoinPool通常适用于那些可以被递归拆分为更小部分的任务。它的典型应用场景包括...

    python 实现多线程下载m3u8格式视频并使用fmmpeg合并

    对于大型视频或高并发下载,可能需要更复杂的策略,比如使用线程池(`concurrent.futures.ThreadPoolExecutor`)或者异步IO(`asyncio`)来更有效地管理和控制资源。此外,合并过程也可以优化,例如,可以在下载的...

Global site tag (gtag.js) - Google Analytics