当前位置: 首页 > news >正文

线程池-面试

线程池定义

线程池是一种线程管理机制,通过预先创建并维护一组线程,避免频繁创建和销毁线程的开销。任务提交到线程池后,由池中的线程执行,执行完毕后线程返回池中等待新任务。

线程池的优点

  • 降低资源消耗:复用已创建的线程,减少线程创建和销毁的开销。

  • 提高响应速度:任务到达时无需等待线程创建即可立即执行。

  • 提高线程可管理性:统一分配、监控和调优线程资源。

  • 避免过载风险:通过队列和拒绝策略控制并发任务数量。

核心类和接口

  • Executor:顶层接口,定义执行任务的方法 execute(Runnable)

  • ExecutorService:扩展 Executor,增加了任务提交、关闭管理等功能。

  • ThreadPoolExecutor:线程池的核心实现类。

  • ScheduledExecutorService:支持定时或周期性任务调度。

ThreadPoolExecutor 核心构造参数

public ThreadPoolExecutor(int corePoolSize,      // 核心线程数int maximumPoolSize,   // 最大线程数long keepAliveTime,    // 非核心线程空闲存活时间TimeUnit unit,         // 时间单位BlockingQueue<Runnable> workQueue, // 任务队列ThreadFactory threadFactory,       // 线程工厂RejectedExecutionHandler handler   // 拒绝策略
)
1. corePoolSize (核心线程数)
  • 定义:线程池中保持存活的最小线程数量,即使这些线程处于空闲状态。

  • 工作方式

    • 当新任务提交时,如果当前线程数 小于 corePoolSize,即使有其他工作线程空闲,线程池也会立即创建一个新的核心线程来处理该任务。

    • 核心线程默认不会因为空闲太久而被回收,除非设置了 allowCoreThreadTimeOut(true)

2. maximumPoolSize (最大线程数)
  • 定义:线程池允许创建的最大线程数量。

  • 工作方式

    • 当任务数量激增,导致工作队列已满时,线程池会创建新的、非核心线程来处理任务,直到线程总数达到 maximumPoolSize

    • 这个参数限制了线程池所能承载的并发能力的上限。

3. keepAliveTime + unit (线程存活时间)
  • 定义:当线程池中的线程数量超过 corePoolSize 时,非核心线程在空闲状态下的存活时间。

  • 工作方式

    • 如果一个非核心线程在 keepAliveTime 时间内没有获取到新任务,它将被终止并回收,从而减少系统资源消耗。

    • 如果调用了 allowCoreThreadTimeOut(true),此策略也会应用于核心线程

4. workQueue (工作队列)
  • 定义:用于保存等待执行的任务的阻塞队列(BlockingQueue<Runnable>)。

  • 工作方式

    • 当线程池中的线程数达到 corePoolSize 后,新来的任务会被放入 workQueue 中等待,而不是直接创建新线程。

    • 队列的选择对线程池的运行行为有重大影响。常见的有:

      • LinkedBlockingQueue(无界队列):任务可以无限堆积,直到耗尽内存。maximumPoolSize 参数将失效。

      • ArrayBlockingQueue(有界队列):可以设置固定容量。有助于防止资源耗尽,但需要与 maximumPoolSize 配合调整。

      • SynchronousQueue(同步移交队列):它不存储元素。每个插入操作必须等待另一个线程的移除操作。这将导致线程池总是创建新线程(除非达到 maximumPoolSize),通常要求很大的 maximumPoolSize

5. threadFactory (线程工厂)
  • 定义:用于创建新线程的工厂(ThreadFactory)。

  • 工作方式

    • 线程池通过调用 ThreadFactory 的 newThread(Runnable r) 方法来创建所有线程。

    • 你可以自定义 ThreadFactory,来设置线程的名称、优先级、是否为守护线程(daemon)等,便于监控和调试。例如,给线程命名为 my-pool-thread-1

6. handler (拒绝策略处理器)
  • 定义:当线程池和工作队列都已饱和(线程数达到 maximumPoolSize 且队列已满)时,用于处理新提交任务的策略(RejectedExecutionHandler)。

  • 内置策略

    • AbortPolicy(默认):直接抛出 RejectedExecutionException 异常。

    • CallerRunsPolicy:由提交任务的调用者线程(通常是主线程)自己来执行这个任务。这是一种简单的反馈机制,可以降低新任务的提交速度。

    • DiscardPolicy:默默丢弃无法处理的任务,不抛出任何异常。

    • DiscardOldestPolicy:丢弃队列中最旧的一个任务,然后尝试重新提交当前任务。

    线程池的工作流程

    1. 提交任务后,若核心线程数未满,创建新线程执行任务。

    2. 核心线程已满时,任务进入阻塞队列等待。

    3. 队列满且线程数未达最大值,创建非核心线程执行任务。

    4. 线程数达到最大值且队列满,触发拒绝策略。

    Executors 提供的常见线程池

    • newFixedThreadPool:固定大小线程池,队列无界,可能堆积任务导致 OOM。

    • newCachedThreadPool:线程数无界,空闲线程超时回收,可能创建过多线程。

    • newSingleThreadExecutor:单线程池,队列无界。

    • newScheduledThreadPool:支持定时任务。

    不推荐使用 Executors 的原因
    其预设的线程池参数可能导致资源耗尽(如无界队列引发 OOM),推荐手动配置 ThreadPoolExecutor

    合理配置线程池参数

    • corePoolSize:CPU 密集型任务设置为 CPU 核数 + 1;IO 密集型任务可参考 CPU 核数 * 2

    • workQueue:有限队列(如 ArrayBlockingQueue)避免无界队列堆积。

    • maximumPoolSize:根据系统负载和任务特性调整,避免过高导致上下文切换开销。

    线程池的生命周期

    • RUNNING:接受新任务并处理队列中的任务。

    • SHUTDOWN:不再接受新任务,但处理队列中的任务。

    • STOP:中断所有线程,丢弃队列任务。

    • TIDYING:所有任务终止,线程数为 0,准备执行 terminated() 钩子。

    • TERMINATEDterminated() 执行完毕,线程池彻底关闭。

    通过 shutdown()shutdownNow() 触发状态转换。


    文章转载自:

    http://pXBzQOyj.xhmxd.cn
    http://s5CgB1cp.xhmxd.cn
    http://iM4gRs7p.xhmxd.cn
    http://kZHULShw.xhmxd.cn
    http://sLHbKQU9.xhmxd.cn
    http://OP2qRrFP.xhmxd.cn
    http://RBMQLCbT.xhmxd.cn
    http://xjThV8PA.xhmxd.cn
    http://eFxSW8ZM.xhmxd.cn
    http://wLKTOZs9.xhmxd.cn
    http://VfgKxG7Y.xhmxd.cn
    http://bmz8l76r.xhmxd.cn
    http://FzvAndiX.xhmxd.cn
    http://c6hNuVj5.xhmxd.cn
    http://sXAjwGk5.xhmxd.cn
    http://5NEsi6D4.xhmxd.cn
    http://fXlqD7m4.xhmxd.cn
    http://5aJiGkP7.xhmxd.cn
    http://JKBYva3S.xhmxd.cn
    http://dcw5FqUH.xhmxd.cn
    http://0yX4vRsj.xhmxd.cn
    http://SSyimWjv.xhmxd.cn
    http://KXAwRo82.xhmxd.cn
    http://LaHplzAl.xhmxd.cn
    http://AeAW7tSm.xhmxd.cn
    http://O4Pexkaw.xhmxd.cn
    http://nomTsM00.xhmxd.cn
    http://U6MGH8Kb.xhmxd.cn
    http://rKsKTcoo.xhmxd.cn
    http://1kA2ZSPz.xhmxd.cn
    http://www.dtcms.com/a/386986.html

    相关文章:

  • 设计模式学习笔记(一)
  • 贪心算法应用:旅行商问题最近邻算法(TSP Nearest Neighbor)
  • 高系分七:软件工程
  • spark hive presto doris 对substr函数的差异
  • webpack5
  • M:Dijkstra算法求最短路径
  • C++11 atomic
  • 工作中真正常用的 git 操作
  • 【Java】P5 Java流程控制——分支结构详解
  • 下载 | Win10 2021官方精简版,预装应用极少!(9月更新、Win 10 IoT LTSC 2021版、适合老电脑安装)
  • 【面试场景题】交易流水表高qps写入会有锁等待或死锁问题吗
  • 嵌入式系统arm高级系统调试技能-24./proc/slabinfo 文件解读与内存异常分析
  • 关于单片机编程的循环以及全局变量应用的思考
  • C++string类详解
  • 卷积神经网络搭建实战(一)-----torch库中的MNIST手写数字数据集(简明版)
  • 2025 Android 知识体系总结(含面试要点,持续补充,更新中...)
  • elementui中表单先上传但不请求接口,点击按钮后在请求接口的方式上传文件,及校验
  • el-input自动填充与设置input背景色无效
  • java设计模式-工厂模式(文件上传)
  • Keras+Flask手写数字识别Web应用
  • PPTist+cpolar:开源演示文稿的远程创作方案
  • Chapter8—组合模式
  • vmware的ub系统长时间不动会黑屏
  • 从0到1打造一个能上传任意GeoJSON的交互式Web地图
  • 深入理解数据结构之复杂度
  • Silicon EFR32xG22 CMU
  • 运维面试笔记(持续补充版)
  • 托福阅读35-1
  • qt QCandlestickSet详解
  • 在Linux和Windows系统下使用Qt监测U盘的插拔事件