一分钟跟着咱奶学会如何创建和使用线程池

前言

在 Java 开发中,线程池是管理多线程任务的核心工具,它能有效复用线程、减少资源消耗。接下来坐稳扶好,跟着咱奶发车啦!


一、为什么要用线程池?

  • 资源复用:避免频繁创建/销毁线程(一次性筷子和家里面的筷子).
  • 控制并发:防止无限制创建线程导致系统崩溃(一直买一次性筷子费时费力)。
  • 管理任务:统一管理任务队列和线程生命周期。

二 、线程池的核心参数

  • 核心线程(长期工):足浴店长期雇佣的正式员工(核心线程数 corePoolSize)。
  • 非核心线程(暑假工):旺季时临时招聘的短期工(最大线程数 maximumPoolSize - 核心线程数)。
  • 客人(任务):需要服务的顾客(提交的 RunnableCallable 任务)。
  • 等候区(任务队列):顾客等待服务的区域(workQueue 队列)。
  • 服务员存活时间(线程空闲时间):临时工(非核心线程)空闲多久后被解雇(keepAliveTime)。
  • 满员策略(拒绝策略):当等候区满且员工全忙时,如何处理新顾客(handler 拒绝策略)。

三、深入解释线程池的核心

1. corePoolSize(核心线程数)
  • 比喻:足浴店长期雇佣的 正式员工数量
  • 规则
    • 即使没有客人,正式员工也会在店里待命(核心线程不会销毁)。
    • 日常客流由他们处理。

2. maximumPoolSize(最大线程数)
  • 比喻:足浴店最多能雇佣的 员工总数(正式工 + 临时工)。
  • 规则
    • 当客人暴增时,店长会临时雇佣 暑假工(非核心线程)。
    • 总员工数不能超过这个最大值。

3. keepAliveTime(线程空闲存活时间)
  • 比喻:临时工(暑假工) 空闲多久后被解雇
  • 规则
    • 当客流减少,临时工长时间没活干(超过 keepAliveTime),会被解雇。
    • 正式工(核心线程)默认不会被解雇(除非设置 allowCoreThreadTimeOut)。

4. workQueue(任务队列)
  • 比喻:顾客的 等候区座位数
  • 规则
    • 当正式工和临时工都在忙时,新客人先到等候区排队。
    • 如果等候区座位用完了(队列满),才会雇佣新的临时工(创建新线程)。

5. handler(拒绝策略)
  • 比喻:当等候区满且所有员工都忙时,店长如何应对新客人:
    • AbortPolicy(默认):直接拒绝客人,并大喊:“客满了!下次再来!”(抛异常)。
    • CallerRunsPolicy:让客人自己动手按脚(提交任务的线程自己去执行任务)。
    • DiscardPolicy:假装没看见新客人,直接忽略(丢弃任务)。
    • DiscardOldestPolicy:把等候区里等最久的客人请走,让新客人进来(丢弃队列头部任务)。

四、 线程池运行流程(划重点)

  1. 日常客流:正式工(核心线程)处理客人(任务)。
  2. 客流增加
    • 客人先到等候区(任务队列)排队。
    • 如果等候区满了,店长雇佣临时工(非核心线程)处理新客人。
  3. 客流高峰
    • 当员工总数(正式工 + 临时工)达到 maximumPoolSize,且等候区也满时,触发拒绝策略。
  4. 客流减少
    • 临时工(非核心线程)空闲超过 keepAliveTime 后被解雇。
    • 正式工(核心线程)继续待命。

代码示例类比

ThreadPoolExecutor spaExecutor = new ThreadPoolExecutor(
    3,                      // 正式工 3 人(corePoolSize)
    10,                     // 总员工最多 10 人(maximumPoolSize)
    30,                     // 临时工空闲 30 秒后解雇(keepAliveTime)
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(5),    // 等候区 5 个座位(workQueue)
    new ThreadPoolExecutor.CallerRunsPolicy()  // 客满时让客人自己按脚(拒绝策略)
);

// 提交任务(客人进店)
spaExecutor.execute(() -> {
    System.out.println("客人享受足浴服务...");
});

五、关键总结

通过足浴店的比喻,可以轻松记住线程池的核心逻辑:

  1. 长期工干活,临时工救急
  2. 先排队,后加人,最后拒绝
  3. 临时工干完活不能白养着(超时解雇)。

这种生活化的类比能帮助理解复杂的线程池机制,避免死记硬背参数!

你可能感兴趣的:(java,面试,开发语言)