707.既 然 提 到 可 以 通 过 配 置 不 同 参 数 创 建 出 不 同 的 线 程 池 , 那 么 Java 中 默 认 实 现 好 的 线 程 池 又 有 哪 些 呢 ? 请 比 较 它 们 的 异 同 。
1. SingleThreadExecutor 线 程 池
这 个 线 程 池 只 有 一 个 核 心 线 程 在 工 作 , 也 就 是 相 当 于 单 线 程 串 行 执 行 所有 任 务 。 如 果 这 个 唯 一 的 线 程 因 为 异 常 结 束 , 那 么 会 有 一 个 新 的 线 程 来 替 代 它 。 此 线 程 池 保 证 所 有 任 务 的 执 行 顺 序 按 照 任 务 的 提 交 顺 序 执 行 。
- corePoolSize: 1, 只 有 一 个 核 心 线 程 在 工 作 。
- maximumPoolSize: 1。
- keepAliveTime: 0L。
- workQueue: new LinkedBlockingQueue
<Runnable>
(), 其 缓 冲 队 列是 无 界 的 。
2. FixedThreadPool 线 程 池
FixedThreadPool 是 固 定 大 小 的 线 程 池 , 只 有 核 心 线 程 。 每 次 提 交 一 个 任 务 就 创 建 一 个 线 程 , 直 到 线 程 达 到 线 程 池 的 最 大 大 小 。 线 程 池 的 大 小 一 旦 达 到 最 大 值 就 会 保 持 不 变 , 如 果 某 个 线 程 因 为 执 行 异 常 而 结 束 , 那 么 线 程 池 会 补 充 一 个 新 线 程 。
FixedThreadPool 多 数 针 对 一 些 很 稳 定 很 固 定 的 正 规 并 发 线 程 , 多 用 于 服 务 器 。
- corePoolSize: nThreads
- maximumPoolSize: nThreads
- keepAliveTime: 0L
- workQueue: new LinkedBlockingQueue
<Runnable>
(), 其 缓 冲 队 列是 无 界 的 。
3. CachedThreadPool 线 程 池
CachedThreadPool 是 无 界 线 程 池 , 如 果 线 程 池 的 大 小 超 过 了 处 理 任 务 所 需 要 的 线 程 , 那 么 就 会 回 收 部 分 空 闲 ( 60 秒 不 执 行 任 务 ) 线 程 , 当 任 务 数 增 加 时 , 此 线 程 池 又 可 以 智 能 的 添 加 新 线 程 来 处 理 任 务 。
线 程 池 大 小 完 全 依 赖 于 操 作 系 统 ( 或 者 说 JVM) 能 够 创 建 的 最 大 线 程 大 小 。 SynchronousQueue 是 一 个 是 缓 冲 区 为 1 的 阻 塞 队 列 。
缓 存 型 池 子 通 常 用 于 执 行 一 些 生 存 期 很 短 的 异 步 型 任 务 , 因 此 在 一 些 面 向 连 接 的 daemon 型 SERVER 中 用 得 不 多 。 但 对 于 生 存 期 短 的 异 步任 务 , 它 是 Executor 的 首 选 。
- corePoolSize: 0
- maximumPoolSize: Integer.MAX_VALUE
- keepAliveTime: 60L
- workQueue: new SynchronousQueue
<Runnable>
(), 一 个 是 缓 冲 区为 1 的 阻 塞 队 列 。
4. ScheduledThreadPool 线 程 池
ScheduledThreadPool: 核 心 线 程 池 固 定 , 大 小 无 限 的 线 程 池 。 此 线 程 池 支 持 定 时 以 及 周 期 性 执 行 任 务 的 需 求 。 创 建 一 个 周 期 性 执 行 任 务 的 线 程 池 。 如 果 闲 置 , 非 核 心 线 程 池 会 在 DEFAULT_KEEPALIVEMILLIS 时 间 内 回 收 。
- corePoolSize: corePoolSize
- maximumPoolSize: Integer.MAX_VALUE
- keepAliveTime: DEFAULT_KEEPALIVE_MILLIS
- workQueue: new DelayedWorkQueue()