`

ThreadPoolExecutor线程池参数设置技巧

    博客分类:
  • java
 
阅读更多
一、ThreadPoolExecutor的重要参数
 
  • corePoolSize:核心线程数
    • 核心线程会一直存活,及时没有任务需要执行
    • 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
    • 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
  • queueCapacity:任务队列容量(阻塞队列)
    • 当核心线程数达到最大时,新任务会放在队列中排队等待执行
  • maxPoolSize:最大线程数
    • 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
    • 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
  • keepAliveTime:线程空闲时间
    • 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
    • 如果allowCoreThreadTimeout=true,则会直到线程数量=0
  • allowCoreThreadTimeout:允许核心线程超时
  • rejectedExecutionHandler:任务拒绝处理器
    • 两种情况会拒绝处理任务:
      • 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
      • 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
    • 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
    • ThreadPoolExecutor类有几个内部实现类来处理这类情况:
      • AbortPolicy 丢弃任务,抛运行时异常
      • CallerRunsPolicy 执行任务
      • DiscardPolicy 忽视,什么都不会发生
      • DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
    • 实现RejectedExecutionHandler接口,可自定义处理器
 
二、ThreadPoolExecutor执行顺序:
     线程池按以下行为执行任务

 

  1. 当线程数小于核心线程数时,创建线程。
  2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
  3. 当线程数大于等于核心线程数,且任务队列已满
    1. 若线程数小于最大线程数,创建线程
    2. 若线程数等于最大线程数,抛出异常,拒绝任务
 
三、如何设置参数
 
  • 默认值
    • corePoolSize=1
    • queueCapacity=Integer.MAX_VALUE
    • maxPoolSize=Integer.MAX_VALUE
    • keepAliveTime=60s
    • allowCoreThreadTimeout=false
    • rejectedExecutionHandler=AbortPolicy()
  • 如何来设置
    • 需要根据几个值来决定
      • tasks :每秒的任务数,假设为500~1000
      • taskcost:每个任务花费时间,假设为0.1s
      • responsetime:系统允许容忍的最大响应时间,假设为1s
    • 做几个计算
      • corePoolSize = 每秒需要多少个线程处理? 
        • threadcount = tasks/(1/taskcost) =tasks*taskcout =  (500~1000)*0.1 = 50~100 个线程。corePoolSize设置应该大于50
        • 根据8020原则,如果80%的每秒任务数小于800,那么corePoolSize设置为80即可
      • queueCapacity = (coreSizePool/taskcost)*responsetime
        • 计算可得 queueCapacity = 80/0.1*1 = 80。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行
        • 切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。
      • maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost)
        • 计算可得 maxPoolSize = (1000-80)/10 = 92
        • (最大任务数-队列容量)/每个线程每秒处理能力 = 最大线程数
      • rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理
      • keepAliveTime和allowCoreThreadTimeout采用默认通常能满足
  • 以上都是理想值,实际情况下要根据机器性能来决定。如果在未达到最大线程数的情况机器cpu load已经满了,则需要通过升级硬件(呵呵)和优化代码,降低taskcost来处理。
分享到:
评论

相关推荐

    线程池代码

    - 调整线程池参数以适应具体应用需求,例如,根据服务器性能和任务特性设置合适的线程数。 - 避免使用`Executors`静态工厂方法创建线程池,因为它们创建的线程池可能无法满足复杂应用的需求,建议直接实例化`...

    线程池示例代码

    合理设置线程池参数、选择合适的工作队列类型以及正确地管理和调度任务,都能帮助系统更好地应对高并发场景,同时保持资源的高效利用。因此,深入研究线程池的实现和使用技巧对于提升系统性能至关重要。

    Java并发编程之ThreadPoolExecutor详解与实战

    主要涵盖ThreadPoolExecutor的基础概念介绍,创建配置参数的意义与选择方法,以及在实际编程中的几种典型应用场景,如任务的异步处理和周期定时任务调度。通过实例演示了如何利用ThreadPoolExecutor构建高效稳定的...

    socket 线程池实现

    Socket线程池是一种高效管理网络连接的技术,它结合了Socket通信和线程池的设计思想,以提高系统的并发处理能力和资源利用率。...通过合理配置线程池参数,可以更好地适应不同场景的需求,实现高效稳定的网络服务。

    Java线程池介绍Java开发Java经验技巧共8页.pd

    - 定期分析线程池状态,根据实际情况调整参数。 理解并熟练运用Java线程池,不仅可以提升程序性能,还能有效控制并发问题,是Java开发中不可或缺的一项技能。在实际开发中,要结合具体业务场景,灵活选择和配置...

    聊聊并发(3)Java线程池的分析和使用Java开发Jav

    1. **合理设置线程池参数**:过大可能导致资源浪费,过小可能影响并发性能。应根据系统资源和任务特性进行调整。 2. **避免长时间持有任务**:线程池中的线程如果长时间处理任务,可能导致其他任务无法及时执行。 3....

    Zz: java 线程池设计思想

    在实际应用中,选择合适的线程池参数至关重要。例如,对于CPU密集型任务,通常设置较小的`corePoolSize`和`maximumPoolSize`以减少线程切换开销;而对于I/O密集型任务,可适当增加线程数量以充分利用CPU资源。 了解...

    JAVA并发编程实践-线程池-学习笔记

    Java并发编程实践中的线程池是一个关键的概念,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,以提高系统的性能和...在实践中,应结合具体业务需求灵活调整线程池参数,以达到最佳的并发执行效果。

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

    `ThreadPoolExecutor`允许我们自定义线程池的关键参数,如核心线程数、最大线程数、工作队列类型等。 #### 线程池关键参数 - **corePoolSize**:线程池中核心线程的数量。这些线程将始终存在,即使没有任务执行。 ...

    java_thread_cn.rar_Java 线程池_java thread books_java线程_线程池_线程池调度

    在实际应用中,合理配置线程池参数是非常关键的。比如,设置适当的核心线程数可以确保系统在处理高并发时有足够的资源,而设置合适的最大线程数则可以防止资源过度消耗。此外,线程池的关闭也需要妥善处理,以确保...

    定制化线程池实现高并发数据处理.zip

    - 在处理大数据量时,合理设置线程池参数可以避免资源过度消耗,防止系统负载过大。 - 使用线程池可以有效地控制并发数量,避免过多的线程导致系统不稳定。 - 分解大任务为小任务,通过线程池并行处理,可以显著...

    50879510A6_Java线程池_funbde_

    `ThreadPoolExecutor`是Java线程池的核心实现类,它的构造函数接受多个参数,用于定制线程池的行为: 1. corePoolSize:核心线程数,线程池会尽量保持这个数量的线程活跃,即使它们空闲。 2. maximumPoolSize:最大...

    多线程控制、线程池模型、HTTP线程.rar

    线程池参数包括核心线程数、最大线程数、线程存活时间、任务队列等,合理配置这些参数对系统性能有很大影响。 3. **HTTP线程**: HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于客户端和服务器...

    concurrent_ext:通过设置线程池队列大小解决解决执行堆栈已满的情况下,主进程还在不断添加任务,会导致内存爆满

    "concurrent_ext"这个项目显然关注的就是如何通过设置线程池的队列大小来避免这种情况。 线程池(ThreadPoolExecutor)是Python标准库`concurrent.futures`模块中的一个关键组件,它允许我们预先创建一定数量的线程...

    Android应用源码之SundPoolSample-IT计算机-毕业设计.zip

    1. 线程池的初始化:观察开发者是如何配置线程池参数的,如corePoolSize、maximumPoolSize、keepAliveTime和workQueue等。 2. 任务提交:分析Task类的实现,理解如何将任务添加到线程池,以及如何控制任务的执行顺序...

    java并发编程艺术

    3. **并发工具类**:介绍Java并发包(java.util.concurrent)中的各种工具类,如Semaphore信号量、CountDownLatch倒计时器、CyclicBarrier回环栅栏、ThreadPoolExecutor线程池等,以及如何在实际编程中合理使用它们...

    ThreadPoolStudy.rar

    在实际开发中,正确选择和配置线程池参数对于系统性能至关重要。比如,选择合适的工作队列类型可以影响并发性能,设置合理的线程池大小可以避免资源浪费,而考虑是否开启核心线程超时则关乎系统的响应速度和稳定性。...

    线程池技术在网络游戏服务器中的应用

    它们允许开发者定制线程池的参数,如核心线程数、最大线程数、线程存活时间、工作队列类型等,以适应不同的服务需求。 总的来说,线程池技术在网络游戏服务器中的应用是优化并发处理、提高系统效率的关键手段。通过...

    Java concurrency线程池之线程池原理(一)_动力节点Java学院整理

    合理设置线程池参数对于提高系统性能至关重要。通常需要考虑系统的CPU核数、任务性质(是否IO密集或计算密集)、任务量等因素来确定`corePoolSize`、`maximumPoolSize`和工作队列容量。 7. **总结** `...

    多线程操作源码 锁和线程池 非IOCP

    它允许我们设置核心线程数、最大线程数、线程存活时间、任务队列等参数。在C#中,`System.Threading.ThreadPool`类提供了类似的线程池功能。在Python中,我们可以使用`concurrent.futures`模块的ThreadPoolExecutor...

Global site tag (gtag.js) - Google Analytics