• 第十五章 线程池的选用与线程数的指定


    注意:本章主要参考自《大型分布式Java应用:基础与实践》和《大型网站技术架构:核心原理与案例分析》

    1、选用的两个角度

    • 高性能:将提交到线程池中的任务直接交给线程去处理(前提:线程数小于最大线程数),不入队
    • 缓冲执行:希望提交到线程池的任务尽量被核心线程(corePoolSize)执行掉

    2、高性能

    • 队列:SynchronousQueue
    • 最大线程数:一般设为Integer.MAX_VALUE(整数最大值),防止回绝任务
    • 典型案例:newCachedThreadPool
    • 尤其适合于执行耗时短的任务

    注意:

    • 设置好闲置失效时间,keepAliveTime,用于避免资源大量耗费
    • 对于出现大量耗时长的任务,容易造成线程数迅速增加,这种情况要衡量使用该类线程池是否合适

    3、缓冲执行

    • 队列:LinkedBlockingQueue和ArrayBlockingQueue
    • 典型案例:newFixedThreadPool(int threadSize)

    注意:

    • 使用该类线程池,最好使用LinkedBlockingQueue(无界队列),但是当大量并发任务的涌入,导致核心线程处理不过来,队列元素会大量增加,可能会报内存溢出
    • 当然,对于上边这种情况的话,如果是ArrayBlockingQueue的话,如果设置得当,可以回绝一些任务,而不报内存溢出

    4、线程数的确定

    • 公式:启动线程数=[任务执行时间/(任务执行时间-IO等待时间)]*CPU核数

    注意:

    • 如果任务大都是CPU计算型任务,启动线程数=CPU核数+1
    • 如果任务大多需要等待磁盘操作,网络响应,(IO密集型),启动线程数
      • 可以参照公式估算,当然>CPU核数
      • 2*cpu
      • cpu/(1-0.8~0.9), eg 8核/(1-0.9)=80

    总结:

    一般使用线程池,按照如下顺序依次考虑(只有前者不满足场景需求,才考虑后者):

    newCachedThreadPool-->newFixedThreadPool(int threadSize)-->ThreadPoolExecutor

    • newCachedThreadPool不需要指定任何参数
    • newFixedThreadPool需要指定线程池数(核心线程数==最大线程数)
    • ThreadPoolExecutor需要指定核心线程数、最大线程数、闲置超时时间、队列、队列容量,甚至还有回绝策略和线程工厂

    对于:newFixedThreadPool和ThreadPoolExecutor的核心数可以参照上述给出的公式进行估算。

  • 相关阅读:
    sql语句之case when null 解决方法
    sql server分组按顺序编号(转+补充)
    非IE用window.open弹出窗口并向父窗口传值
    IE6浏览器弹出窗口,父窗口传值
    sql之储存过程与函数的区别
    sql之执行事务性语句
    c#获取与筛选对象相匹配的所有DataRow对象数组
    ?: 运算符(C# 参考)
    Mysql 5.7优化
    libcurl.a 跨平台
  • 原文地址:https://www.cnblogs.com/java-zhao/p/5150781.html
Copyright © 2020-2023  润新知