• 【学习笔记】线程池


    一、初识线程池

    1、什么是“池”

    需要的时候可以快速使用,不用重新收集

    2、线程池

    • 如果不使用线程池,每个任务都新开一个线程处理
    • 加快响应速度
    • 合理利用CPU和内存
    • 统一管理

    3、线程池适合应用的场合

    • 批量计算任务、服务器处理请求、excel解析
    • 实际上,在开发中,如果需要创建5个以上的线程,那么就可以使用线程池来管理

    二、 创建和停止线程池:

    1、线程池构造方法的参数

    参数名类型含义
    corePoolSizeint核心线程数
    maxPoolSizeint最大线程数
    keepAliveTimelong保持存活时间
    workQueueBlockingQueue任务存储队列
    threadFactoryThreadFactory当线程池需要新的线程时,会使用ThreadFactory来生成新的线程
    HandlerRejectedExecutionHandler由于线程池无法接受你提交的任务的拒绝策略

    (1)corePoolSize指的是核心线程数:线程池在完成初始化后,默认情况下,线程池中并没有任何线程,线程池会等待有任务到来时,再创建新线程去执行任务

    (2)最大量maxPoolSize:在核心线程数的基础上,额外增加的线程数的上限

    (3)添加线程规则:

    • 最开始线程总数小于corePoolSize时,即使有线程处于空闲状态,新任务到来时,也会创建一个新线程
    • 直到线程数等于corePoolSize,再来任务时,会把任务放入队列去等待
    • 直到队列也满了,如果此时线程数小于maxPoolSize,则会再创建新线程来执行任务
    • 如果队列已满,并且线程数已经扩大到等于maxPoolSize时,再尝试添加任务时,会被拒绝

    (4)增减线程的特点

    • 通过设置corePoolSize和maxPoolSize相同,就可以创建固定大小的线程池
    • 线程池希望保持较少的线程数,并且只有在负载变得很大时才增加它
    • 通过设置maxPoolSize为很高的值,可以允许线程池容纳任意数量的并发任务
    • 只有在队列填满时才创建多于corePoolSize的线程,如果使用的是无界队列,那么线程数就不会超过corePoolSize

    2、线程存活时间:keepAliveTime

    如果线程池当前的线程数多于corePoolSize,那么如果多于的线程空闲时间超过keepAliveTime,它们就会被终止

    3、创建线程:ThreadFactory

    • 默认使用Executors.defaultThreadFactory()
    • 创建出来的线程都在同一个线程组
    • 如果自己指定ThreadFactory,那么就可以改变线程名、线程组、优先级是否是守护线程等
    • 通常情况下,使用默认的线程工厂基本上就可以满足绝大多数的需要

    4、工作队列:

    有3种最常见的队列类型

    1. 直接交换:SynchronousQueue

    2. 无界队列:LinkedBlockingQueue

    3. 有界队列:ArrayBlockingQueue

    5、守护线程

    守护线程和普通线程(也成为用户线程)的区别主要在于是否影响jvm的结束。具体而言,如果普通线程没有结束运行的话,jvm也是不会停止运行的,但是假设所有的用户线程都已经结束了,而只剩下守护线程,那么jvm便会认为此时没有继续运行的必要,从而停止。

    非常典型的守护线程就是我们的垃圾处理器,也就是GC。

    在平时的学习和工作中,是否需要去把线程设置为守护线程呢?
    答案是,通常情况下没有必要,因为我们假设把线程设置为守护线程,那么一旦其他的线程都已终止,只剩下这个线程的话,无论这个线程正在执行什么任务,它都会被停止。假设我们正在读取文件,那么可能会造成数据只读到一般的情况,或者是其他各种各样的问题。
    所以在平时的学习工作中,我们只需要去创建普通的线程就可以了,对于守护线程,只需要了解它的概念和特点。

    6、线程池应该手动创建还是自动创建:

    • 手动创建更好,因为这样可以更加明确线程池的运行规则,避免资源耗尽的风险
    • newFixedThreadPool 容易造成大量内存占用,可能会导致OOM
    • newSingleThreadExecutor 当请求堆积的时候,可能会占用大量的内存
    • CachedThreadPool:可缓存线程池
      特点:具有自动回收多余线程的功能
      弊端在于第二个参数maximumPoolSize被设置为了Integer.MAX_VALUE,这可能会创建数量 非常多的线程,甚至导致OOM
    • newScheduledThreadPool

    7、正确的创建线程池的方法:

    • 根据不同的业务场景,设置线程池参数
    • 比如:内存有多大,给线程取什么名字等等

    8、线程池里的线程数量设定为多少比较合适:

    • CPU密集型(加密、计算hash等):最佳线程数为CPU核心数的1-2倍

    • 耗时IO型(读写数据库、文件、网络读写等):最佳线程数一般会大于CPU核心数很多倍

            参考Brain Goetz推荐的计算方法:
      
            线程数 = CPU核心数*(1 + 平均等待时间/平均工作时间)
      
      • 1
      • 2
      • 3

    9、常见线程池的特点:

    • FixedThreadPool
      核心线程池和最大线程数相同,队列满后,无法再增加线程

    • CachedThreadPool
      具有自动回收多余线程的功能,队列没有容量,线程数可以很多

    • ScheduledThreadPool
      支持定时及周期性任务执行的线程池

    • SingleThreadExecutor
      只会用唯一的工作线程来执行任务(用到的场景并不多)

    10、停止线程池的正确方法:

    1、shutdown
    运行这个方法之后并不一定会停止,事实上,这个方法仅仅是初始化整个关闭过程。运行这个方法,会把正在执行的和队列中等待的都执行完毕之后再关闭,但是不会再增加任务。

    2、isShutdown
    3、isTerminated:线程都结束了返回true
    4、awaitTermination
    5、shutdownNow

    11、任务太多,怎么拒绝:

    拒绝时机:当Executor关闭时,提交新任务会被拒绝,以及当Executor对最大线程和工作队列容量使用有限边界并且已经饱和时

    4种拒绝策略:

    • AbortPlicy:抛出异常
    • DiscardPolicy:默默丢弃
    • DiscardOlderPolicy:丢弃掉老的
    • CallerRunsPolicy

    12、钩子方法,给线程池加点料:

    • 每个执行任务前后
    • 日志、统计

    三、线程池

    1、线程池组成部分:

    • 线程池管理器
    • 工作线程
    • 任务队列
    • 任务接口(Task)

    2、Executor家族:

    线程池、ThreadPoolExecutor、ExecutorService、Executor、Executors等这么多和线程池相关的类,都是什么关系

    • Executor:是一个接口,里面只有一个方法execute
    • ExecutorService:继承Executor,增加了一些新的方法,拥有初步管理线程池的方法
    • Executors:工具类,帮我们快速创建线程池用的

    3、线程池实现任务复用的原理:

    • 相同线程执行不同任务
    • runWorker

    4、线程池五种状态:

    execute方法:执行任务

    状态含义
    RUNNING接受新任务并处理排队任务
    SHUTDOWN不接受新任务但处理排队任务
    STOP不接受新任务,也不处理排队任务,并中断正在进行的任务
    TIDYING所有任务都已终止,workCount为零时,线程会转换到TIDYING状态,并将运行terminate()钩子方法
    TERMINATEDterminate()运行完成

    5、使用线程池的注意点:

    • 手动创建线程池
    • 线程数合理
    • 考虑多个线程池间的影响

    :学习来源——慕课网

  • 相关阅读:
    2022锦江行——非繁城品:疫情之下,存量酒店的突围之道
    前端性能优化:利用防抖节流实现图片懒加载
    更高效的构建工具-vite
    Oracle Data Pump与加密
    JS中数组的遍历方法有那些?
    地平线计划迎新历程,Zebec Chain有望成为公链赛道新兴生力军
    鸢尾花数据可视化
    二维码登录的原理
    YModem协议总结
    文科生的爬藤神器:HIEEC哈佛国际经济学论文比赛
  • 原文地址:https://blog.csdn.net/qq_45192089/article/details/126697409