并发编程面试(三) 线程池

并发编程面试(三) 线程池

Java 中 的 线 程 池 是 如 何 实 现 的 ?

  • 在 Java 中 , 所 谓 的 线 程 池 中 的 “ 线 程 ” , 其 实 是 被 抽 象 为 了 一 个 静 态 内 部 类 Worker, 它 基 于 AQS 实 现 , 存 放 在 线 程 池 的 Hash Set< Worker> workers 成 员 变 量 中 ;

  • 而 需 要 执 行 的 任 务 则 存 放 在 成 员 变 量 work Queue( Blocking Queue< Runnable> work Queue) 中 。

这 样 , 整 个 线 程 池 实 现 的 基 本 思 想 就 是 : 从 work Queue 中 不 断 取 出 需 要 执 行 的 任 务 , 放 在 Workers 中 进 行 处 理 。

创 建 线 程 池 的 几 个 核 心 构 造 参 数 ?

Java 中 的 线 程 池 的 创 建 其 实 非 常 灵 活 , 我 们 可 以 通 过 配 置 不 同 的 参 数 , 创 建 出 行 为 不 同 的 线 程 池 , 这 几 个 参 数 包 括 :

  • core Pool Size: 线 程 池 的 核 心 线 程 数 。

  • maximum Pool Size: 线 程 池 允 许 的 最 大 线 程 数 。

  • keep Alive Time: 超 过 核 心 线 程 数 时 闲 置 线 程 的 存 活 时 间 。

  • work Queue: 任 务 执 行 前 保 存 任 务 的 队 列 , 保 存 由 execute 方 法 提 交 的 Runnable 任 务 。

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

显 然 不 是 的 。 线 程 池 默 认 初 始 化 后 不 启 动 Worker, 等 待 有 请 求 时 才 启 动 。

每 当 我 们 调 用 execute() 方 法 添 加 一 个 任 务 时 , 线 程 池 会 做 如 下 判 断 :

  • 如 果 正 在 运 行 的 线 程 数 量 小 于 core Pool Size, 那 么 马 上 创 建 线 程 运 行 这 个 任 务 ;

  • 如 果 正 在 运 行 的 线 程 数 量 大 于 或 等 于 core Pool Size, 那 么 将 这 个 任 务 放 入 队 列 ;

  • 如 果 这 时 候 队 列 满 了 , 而 且 正 在 运 行 的 线 程 数 量 小 于maximum Pool Size, 那 么 还 是 要 创 建 非 核 心 线 程 立 刻 运 行 这 个 任 务 ;

  • 如 果 队 列 满 了 , 而 且 正 在 运 行 的 线 程 数 量 大 于 或 等 于maximum Pool Size, 那 么 线 程 池 会 抛 出 异 常 Reject Execution Exception。当 一 个 线 程 完 成 任 务 时 , 它 会 从 队 列 中 取 下 一 个 任 务 来 执 行 。 当 一 个线 程 无 事 可 做 , 超 过 一 定 的 时 间 ( keep Alive Time) 时 , 线 程 池 会 判 断 。

如 果 当 前 运 行 的 线 程 数 大 于 core Pool Size, 那 么 这 个 线 程 就 被 停 掉 。 所 以 线 程 池 的 所 有 任 务 完 成 后 , 它 最 终 会 收 缩 到 core Pool Size 的 大 小 。

Java 中 默 认 实 现 好 的 线 程 池 又 有 哪 些 呢 ? 请 比 较 它 们 的 异 同

1.SingleThreadExecutor线程池

这 个 线 程 池 只 有 一 个 核 心 线 程 在 工 作 , 也 就 是 相 当 于 单 线 程 串 行 执 行 所 有 任 务 。 如 果 这 个 唯 一 的 线 程 因 为 异 常 结 束 , 那 么 会 有 一 个 新 的 线 程 来 替 代 它 。 此 线 程 池 保 证 所 有 任 务 的 执 行 顺 序 按 照 任 务 的 提 交 顺 序 执 行 。

  • core Pool Size: 1 , 只 有 一 个 核 心 线 程 在 工 作 。

  • maximum Pool Size: 1 。

  • keep Alive Time: 0 L。

  • work Queue: new Linked Blocking Queue< Runnable>(), 其 缓 冲 队 列 是 无 界 的 。

2. *.* *Fixed* *Thread* *Pool* *线* *程* *池*

Fixed Thread Pool 是 固 定 大 小 的 线 程 池 , 只 有 核 心 线 程 。 每 次 提 交 一 个 任 务 就 创 建 一 个 线 程 , 直 到 线 程 达 到 线 程 池 的 最 大 大 小 。 线 程 池 的 大 小 一 旦 达 到 最 大 值 就 会 保 持 不 变 , 如 果 某 个 线 程 因 为 执 行 异 常 而 结 束 , 那 么 线 程 池 会 补 充 一 个 新 线 程 。

Fixed Thread Pool 多 数 针 对 一 些 很 稳 定 很 固 定 的 正 规 并 发 线 程 , 多 用 于

服 务 器 。

· core Pool Size: n Threads

· maximum Pool Size: n Threads

· keep Alive Time: 0 L

· work Queue: new Linked Blocking Queue< Runnable>(), 其 缓 冲 队 列 是 无 界 的 。

3. *.* *Cached* *Thread* *Pool* *线* *程* *池*

Cached Thread Pool 是 无 界 线 程 池 , 如 果 线 程 池 的 大 小 超 过 了 处 理 任 务 所 需 要 的 线 程 , 那 么 就 会 回 收 部 分 空 闲 ( 60 秒 不 执 行 任 务 ) 线 程 , 当 任 务 数 增 加 时 , 此 线 程 池 又 可 以 智 能 的 添 加 新 线 程 来 处 理 任 务 。

线 程 池 大 小 完 全 依 赖 于 操 作 系 统 ( 或 者 说 JVM) 能 够 创 建 的 最 大 线 程 大 小 。 Synchronous Queue 是 一 个 是 缓 冲 区 为 1 的 阻 塞 队 列 。

缓 存 型 池 子 通 常 用 于 执 行 一 些 生 存 期 很 短 的 异 步 型 任 务 , 因 此 在 一 些 面 向 连 接 的 daemon 型 SERVER 中 用 得 不 多 。 但 对 于 生 存 期 短 的 异 步 任 务 , 它 是 Executor 的 首 选 。

· core Pool Size: 0

· maximum Pool Size: Integer. MAX_ VALUE

· keep Alive Time: 60 L

· work Queue: new Synchronous Queue< Runnable>(), 一 个 是 缓 冲 区 为 1 的 阻 塞 队 列 。

4. *.* *Scheduled* *Thread* *Pool* *线* *程* *池*

Scheduled Thread Pool: 核 心 线 程 池 固 定 , 大 小 无 限 的 线 程 池 。 此 线 程

池 支 持 定 时 以 及 周 期 性 执 行 任 务 的 需 求 。 创 建 一 个 周 期 性 执 行 任 务 的 线 程 池 。 如 果 闲 置 , 非 核 心 线 程 池 会 在 DEFAULT_ KEEPALIVEMILLIS 时 间 内 回 收 。

· core Pool Size: core Pool Size

· maximum Pool Size: Integer. MAX_ VALUE

· keep Alive Time: DEFAULT_ KEEPALIVE_ MILLIS

work Queue: new Delayed Work Queue()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值