706.线 程 池 中 的 线 程 是 怎 么 创 建 的 ? 是 一 开 始 就 随 着 线 程 池 的 启 动 创 建 好 的 吗 ?

显 然 不 是 的 。 线 程 池 默 认 初 始 化 后 不 启 动 Worker, 等 待 有 请 求 时 才 启 动 。
每 当 我 们 调 用 execute() 方 法 添 加 一 个 任 务 时 , 线 程 池 会 做 如 下 判 断 :

  1. 如 果 正 在 运 行 的 线 程 数 量 小 于 corePoolSize, 那 么 马 上 创 建 线 程 运 行 这 个 任 务 ;
  2. 如 果 正 在 运 行 的 线 程 数 量 大 于 或 等 于 corePoolSize, 那 么 将 这 个 任 务 放 入 队 列 ;
  3. 如 果 这 时 候 队 列 满 了 , 而 且 正 在 运 行 的 线 程 数 量 小 于 maximumPoolSize, 那 么 还 是 要 创 建 非 核 心 线 程 立 刻 运 行 这 个 任 务 ;
  4. 如 果 队 列 满 了 , 而 且 正 在 运 行 的 线 程 数 量 大 于 或 等 于maximumPoolSize, 那 么 线 程 池 会 抛 出 异 常 RejectExecutionException。

当 一 个 线 程 完 成 任 务 时 , 它 会 从 队 列 中 取 下 一 个 任 务 来 执 行 。 当 一 个 线 程 无 事 可 做 , 超 过 一 定 的 时 间 ( keepAliveTime) 时 , 线 程 池 会 判 断 。
如 果 当 前 运 行 的 线 程 数 大 于 corePoolSize, 那 么 这 个 线 程 就 被 停 掉 。所 以 线 程 池 的 所 有 任 务 完 成 后 , 它 最 终 会 收 缩 到 corePoolSize 的 大 小 。