不是吧?线程池这样搞?

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 学习线程池能够帮助我们更好地处理多线程编程,并提高程序的性能和稳定性。线程池指定线程数这块,首先要考量自己的业务是什么样的?是cpu密集型的还是io密集型的,假设运行应用的机器CPU核心数是N。 cpu密集型的可以先给到N+1,io密集型的可以给到2N 。

其他系列文章目录

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

系列文章目录

前言

一、为什么需要线程池?

二、举个背景例子

三、怎么创建线程池?

四、线程池指定线程数


前言

学习线程池能够帮助我们更好地处理多线程编程,并提高程序的性能和稳定性


一、为什么需要线程池?

JVM在HotSpot的线程模型下,Java线程会一对一映射为内核线程。

这意味着,在Java中每次创建以及回收线程都会去内核创建以及回收。

这就有可能导致: 创建和销毁线程所花费的时间和资源可能比处理的任务花费的时间和资源要更多。

线程池的出现是为了提高线程的复用性以及固定线程的数量!!!


二、举个背景例子

一个消息管理平台,提供其中一个功能就是: 运营会圈定人群然后群发消息。

主要流程大致就是:创建模板---->定时---->群发消息---->用户收到消息

先说一个概念:HDFS (Hadoop Distributed File System) 是分布式文件系统的一种,用于存储和处理大数据集。它是Hadoop框架的核心组件之一。HDFS可以让用户将大数据集分散在多台计算机上,以提高数据处理能力和可靠性。它将数据拆分为小块并存储在多台计算机上,提供了读写分离、容错机制、数据备份和高可用等特性。HDFS的基本单位是数据块,通常为128MB或256MB。数据块的复制数量和位置由系统自动管理。HDFS对于大数据的存储和管理提供了高度的可靠性和可扩展性,因此被广泛应用于大数据处理和分析领域。

然后运营圈定的人群实际上在模板上只是一个ID、这边要通过ID去获取到HDFS文件,

对HDFS文件进行遍历,然后继续往下发,(接收到定时任务,再对HDFS进行遍历)这里的处理,用的就是线程池处理。

HDFS遍历其实就是IO的操作,把这个过程给异步化,为了提高系统的吞吐量,于是这里用的线程池。即便遍历HDFS出现问题,我们可以建设完备的监控和告警可以及时发现。


三、怎么创建线程池?

阿里巴巴开发手册就有提到,不要使用Executors去创建线程。建议使用ThreadPoolExecutor去创建线程池。

最主要的目的就是:使用ThreadPoolExecutor创建的线程你是更能了解线程池运行的规则,避免资源耗尽的风险。

七个核心参数:

    1. corePoolSize:核心线程数,线程池维护的最少线程数。
    2. maximumPoolSize:最大线程数,线程池维护的最大线程数。
    3. keepAliveTime:线程空闲时间,当线程池中的线程数大于核心线程数时,这些多余的线程会被销毁,这个参数定义了这些线程的空闲时间。
    4. TimeUnit:时间单位,keepAliveTime的时间单位。
    5. workQueue:任务队列,当提交的任务数量大于线程池当前可用的线程数时,任务会被存放在这个队列中。
    6. threadFactory:线程工厂,用于创建线程池中的线程。
    7. handler:拒绝策略,当任务队列已满且线程池中的线程数量已达到最大值时,新提交的任务如何被拒绝执行。常用的拒绝策略有AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy和DiscardPolicy。

    任务提交流程:

      1. 首先会判断运行线程数是否小于coreFoolSize,如果小于,则直接创建新的线程执行任务。
      2. 如果大于corePoolSize,判断workQueue阻塞队列是否已满,如果还没满,则将任务放到阻塞队列中。
      3. 如果workQueue阻塞队列已经满了则判断当前线程数是否大于maximumPoolSize,如果没大于则创建新的线程执行任务。
      4. 如果大于maximumPoolSize,则执行任务拒绝策略 (具体就是你自己实现的handler)。

      这里有个点需要注意下,就是workQueue阻塞队列满了,但当前线程数小于maximumPoolSize,这时候会创建新的线程执行任务。

      不过一般我们都是将corePoolSize和maximumPoolSize设置相同数量。

      keepAliveTime指的就是,当前运行的线程数大于核心线程数了,只要空闲时间达到了,就会对线程进行回收。


      四、线程池指定线程数

      线程池指定线程数这块,首先要考量自己的业务是什么样的??

      是cpu密集型的还是io密集型的,假设运行应用的机器CPU核心数是N

      cpu密集型的可以先给到N+1,io密集型的可以给到2N

      上面这个只是一个常见的经验做法,具体究竟开多少线程,需要压测才能比较准确地定下来。

      注:线程不是说越大越好,在之前的我也提到过,多线程是为了充分利用CPU的资源。如果设置的线程过多,线程大量有上下文切换,这一部分也会带来系统的开销,这就得不偿失了。

      相关实践学习
      基于Hologres轻松玩转一站式实时仓库
      本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
      SaaS 模式云数据仓库必修课
      本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
      目录
      相关文章
      |
      1月前
      |
      监控 Java
      面试官:说一说如何优雅的关闭线程池,我:shutdownNow,面试官:粗鲁!
      【6月更文挑战第4天】面试官:说一说如何优雅的关闭线程池,我:shutdownNow,面试官:粗鲁!
      15 0
      |
      2月前
      |
      Java
      面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
      面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
      27 1
      |
      2月前
      |
      缓存 Java 程序员
      程序员的金三银四:创建线程池有哪几种方式?
      程序员的金三银四:创建线程池有哪几种方式?
      36 0
      |
      存储 缓存 Java
      线程池之刨根问底
      线程池之刨根问底
      106 0
      线程池之刨根问底
      |
      消息中间件 监控 安全
      线程池面试那些事儿!
      相信各位 Javaer 在面试中或多或少肯定被问到过线程池相关问题吧,线程池是一个相对比较复杂的体系,基于此可以问出各种各样、五花八门的问题。 若你很熟悉线程池,如果可以,完全可以滔滔不绝跟面试官扯一个小时线程池,一般面试也就一个小时左右,那么这样留给面试官问其他问题的时间就很少了,或者其他问题可能问的也就不深入了,那你通过面试的几率是不就更大点了呢。
      180 1
      线程池面试那些事儿!
      |
      缓存 监控 Java
      Java多线程-死磕ThreadPoolExecutor线程池
      Java线程池ThreadPoolExecutor基本实现原理
      227 0
      Java多线程-死磕ThreadPoolExecutor线程池
      |
      存储 缓存 监控
      老生常谈的线程池希望你已经都会了
      老生常谈的线程池希望你已经都会了
      405 0
      老生常谈的线程池希望你已经都会了
      |
      Java 调度 数据库
      新手一看就懂的线程池!
      那相信大家也能感受到,其实用多线程是很麻烦的,包括线程的创建、销毁和调度等等,而且我们平时工作时好像也并没有这样来 new 一个线程,其实是因为很多框架的底层都用到了线程池。 线程池是帮助我们管理线程的工具,它维护了多个线程,可以降低资源的消耗,提高系统的性能。 并且通过使用线程池,我们开发人员可以更好的把精力放在任务代码上,而不去管线程是如何执行的,实现任务提交和执行的解藕。 本文将从是何、为何、如何的角度来讲解线程池:
      156 0
      新手一看就懂的线程池!
      |
      缓存 Java 程序员
      产品经理问我:手动创建线程不香吗,为什么非要用线程池呢?
      每次写线程池的文章时,总会想起自己大三第一次面试就是挂在这上面,当时年少轻狂,连SpringBoot是什么都不知道就敢面阿里,真是初生牛犊不怕虎。
      |
      Java
      面试官一个线程池问题把我问懵逼了。 (上)
      面试官一个线程池问题把我问懵逼了。 (上)
      110 0
      面试官一个线程池问题把我问懵逼了。 (上)