《Java 线 程 的 讨 论 与 应 用(转).doc》由会员分享,可在线阅读,更多相关《Java 线 程 的 讨 论 与 应 用(转).doc(10页珍藏版)》请在金锄头文库上搜索。
1、Java 线 程 的 讨 论 与 应 用 (转)日期:2001-3-7 11:20:12Java 线 程 的 讨 论 与 应 用 龙 士 工 一、 为 什 么 要 研 究 和 使 用 线 程 一 般 来 说, 计 算 机 正 在 执 行 的 程 序 称 作 进 程(process), 进 程 有 不 同 的 地 址 空 间 并 且 是 在 同 一 系 统 上 运 行 的 不 同 程 序, 如 和Excel, 进 程 间 的 通 讯 是 很 费 时 而 且 有 限 的。 上 下 文 切 换、 改 变 运 行 的 进 程 也 是 非 常 复 杂 的。 进 程 间 通 讯 复 杂, 可 能 需 要
2、管 道、 消 息 队 列、 共 享 内 存(sharedmemory) 或 信 号 处 理 来 保 证 进 程 间 的 通 讯。 尽 管 许 多 程 序 都 在 运 行, 但 一 次 只 能 与 一 个 程 序 打 交 道。 线 程(thread) 是 指 进 程 中 单 一 顺 序 的 控 制 流。 又 称 为 轻 量 级 进 程。 线 程 则 共 享 相 同 的 地 址 空 间 并 共 同 构 成 一 个 大 的 进 程。 线 程 间 的 通 讯 是 非 常 简 单 而 有 效 的, 上 下 文 切 换 非 常 快 并 且 是 整 个 大 程 序 的 一 部 分 切 换。 线 程 仅 是
3、过 程 调 用, 它 们 彼 此 独 立 执 行, 线 程 使 得 在 一 个 应 用 程 序 中, 程 序 的 编 写 更 加 自 由 和 丰 富。 线 程 的 兴 趣 在 于, 一 个 程 序 中 同 时 使 用 多 个 线 程 来 完 成 不 同 的 任 务。 因 此 如 果 很 好 地 利 用 线 程, 可 以 大 大 简 化 应 用 程 序 设 计。 多 线 程 可 以 增 进 程 序 的 交 互 性, 提 供 更 好 的 能 力 和 功 能、 更 好 的GUI 和 更 好 的 服 务 器 功 能。 给 二 个 例 子 说 明 如 下: 例 一: 利 用 多 线 程 并 行 机 制
4、可 以 很 好 地 解 决 交 互 式 网 络 程 序 中 的 许 多 问 题, 如: 大 量 的 网 络 文 件 资 源 的 读 写、 用 户 输 入 响 应、 动 画 显 示 等 问 题 不 需 要 的 多 少 时 间; 而 耗 时 的 复 杂 计 算 通 常 并 不 需 要 立 即 响 应, 所 以 无 需 将 全 给 它。 例 如, 从 一 个 慢 速 的 网 络 上 读 取 一 数 据 流 也 许 要 分 钟 时 间, 但 需 要 参 与 传 输 数 据 的 时 间 则 非 常 短; 响 应 用 户 的 输 入 如 击 键, 就 算 最 快 的 输 入 员, 秒 钟 击 键 次, 也
5、 不 需 要 的 多 少 时 间。 动 画 程 序 比 较 耗 时, 一 幅 画 在 秒 内 要 重 绘 次, 但 在 大 部 分 时 间 仍 处 于 空 闲 状 态。 在 传 统 的 单 线 程 环 境 下 的 问 题 是 用 户 必 须 等 待 每 个 任 务 完 成 后 才 能 进 行 下 一 个 任 务。 即 使 大 部 分 时 间 空 闲, 也 只 能 按 步 就 班 地 工 作。 多 线 程 可 以 很 好 地 解 决 这 些 问 题 避 免 引 起 用 户 的 等 待。 如: 耗 时 的 复 杂 计 算 应 用 就 可 划 分 成 两 个 控 制 线 程: 一 个 处 理GUI
6、的 用 户 事 件, 另 一 个 进 行 后 台 计 算。 例 二: 如 并 发 服 务 器, 它 面 向 不 定 长 时 间 内 处 理 完 的 请 求, 对 每 个 请 求 由 服 务 器 的 线 程 处 理。 传 统 的 并 发 服 务 器 往 往 是 基 于 多 进 程 机 制 的, 每 个 客 户 一 个 进 程, 需 要 操 作 系 统 的 干 预, 进 程 的 数 目 受 操 作 系 统 的 限 制。 本 文 利 用Java 的 线 程 机 制 建 立 了 基 于 多 线 程 的 并 发 服 务 器。 生 成 和 管 理 他 们 是 相 当 简 单 的 操 作。 线 程 被 用
7、来 建 立 请 求 驱 动 的 服 务 程 序, 每 个 客 户 一 个 线 程, 多 个 线 程 可 以 并 发 执 行。 特 别 地 线 程 具 有 如 下 特 性(1) 线 程 共 享 父 进 程 的 所 有 程 序 和 数 据(2) 有 自 身 的 运 行 单 元(3) 有 它 自 己 的 私 有 存 储 和 执 行 环 境( 尤 其 是 处 理 器 寄 存 器), 使 得 服 务 器 进 程 不 随 客 户 数 的 增 加 而 线 性 增 加。 可 减 少 服 务 器 进 程 的 压 力, 降 低 开 销, 充 分 利 用CPU 的 资 源。 以 上 并 发 服 务 器 在 某 一
8、瞬 间 由 同 一 服 务 器 进 程 所 产 生 的 多 个 并 发 线 程 对 多 个 客 户 的 并 发 请 求 采 取 分 而 治 之 的 措 施, 从 而 解 决 了 并 发 请 求 的 问 题。 各 线 程 即 可 以 独 立 操 作, 又 可 以 协 同 作 业。 降 低 了 服 务 器 的 复 杂 度。 Java 是 基 于 操 作 系 统 级 的 多 线 程 环 境 之 上 设 计 的,Java 的 运 行 器 依 靠 多 线 程 来 执 行 任 务, 并 且 所 有 类 库 在 设 计 时 都 考 虑 到 多 线 程 机 制。 二、Java 线 程 的 结 构 Java 支
9、 持 一 种“ 抢 占 式”(preemptive) 调 度 方 式。 线 程 从 产 生 到 消 失, 可 分5 个 状 态: Newborn 线 程 在 己 被 创 建 但 未 执 行 这 段 时 间 内, 处 于 一 个 特 殊 的Newborn 状 态, 这 时, 线 程 对 象 己 被 分 配 内 存 空 间, 其 私 有 数 据 己 被 初 始 化, 但 该 线 程 还 未 被 调 度。 此 时 线 程 对 象 可 通 过start() 方 法 调 度, 或 者 利 用stop() 方 法 杀 死. 新 创 建 的 线 程 一 旦 被 调 度, 就 将 切 换 到Runnable
10、状 态。 Runnable Runnable 意 即 线 程 的 就 绪 状 态, 表 示 线 程 正 等 待 处 理 器 资 源, 随 时 可 被 调 用 执 行。 处 于 就 绪 状 态 的 线 程 事 实 上 己 被 调 度, 也 就 是 说, 它 们 己 经 被 放 到 某 一 队 列 等 待 执 行。 处 于 就 绪 状 态 的 线 程 何 时 可 真 正 执 行, 取 决 于 线 程 优 先 级 以 及 队 列 的 当 前 状 况。 线 程 的 优 先 级 如 果 相 同, 将 遵 循 先 来 先 服 务 的 调 度 原 则。 线 程 依 据 自 身 优 先 级 进 入 等 待 队
11、 列 的 相 应 位 置。 某 些 系 统 线 程 具 有 最 高 优 先 级, 这 些 最 高 优 先 级 线 程 一 旦 进 入 就 绪 状 态, 将 抢 占 当 前 正 在 执 行 的 线 程 的 处 理 器 资 源, 当 前 线 程 只 能 重 新 在 等 待 队 列 寻 找 自 己 的 位 置. 这 些 具 有 最 高 优 先 级 的 线 程 执 行 完 自 己 的 任 务 之 后, 将 睡 眠 一 段 时 间, 等 待 被 某 一 事 件 唤 醒. 一 旦 被 唤, 这 些 线 程 就 又 开 始 抢 占 处 理 器 资 源。 这 些 最 高 优 先 级 线 程 通 常 用 来 执
12、 行 一 些 关 键 性 任 务, 如 屏 幕 显 示。 低 优 先 级 线 程 需 等 待 更 长 的 时 间 才 能 有 机 会 运 行。 由 于 系 统 本 身 无 法 中 止 高 优 先 级 线 程 的 执 行, 因 此, 如 果 你 的 程 序 中 用 到 了 优 先 级 较 高 的 线 程 对 象, 那 么 最 好 不 时 让 这 些 线 程 放 弃 对 处 理 器 资 源 的 控 制 权, 以 使 其 他 线 程 能 够 有 机 运 行。 Running Running( 运 行) 状 态 表 明 线 程 正 在 运 行, 该 线 己 经 拥 有 了 对 处 理 器 的 控 制
13、权, 其 代 码 目 前 正 在 运 行。 这 个 线 程 将 一 直 运 行 直 到 运 行 完 毕, 除 非 运 行 过 程 的 控 制 权 被 一 优 先 级 更 高 的 线 程 强 占。 综 合 起 来, 线 程 在 如 下3 种 情 形 之 下 将 释 放 对 处 理 器 的 控 制 权: 1. 主 动 或 被 动 地 释 放 对 处 理 器 资 源 的 控 制 权。 这 时, 该 线 程 必 须 再 次 进 入 等 待 队 列, 等 待 其 他 优 先 级 高 或 相 等 线 程 执 行 完 毕。 2. 睡 眠 一 段 确 定 的 时 间, 不 进 入 等 待 队 列。 这 段 确
14、 定 的 时 间 段 到 期 之 后, 重 新 开 始 运 行。 3. 等 待 某 一 事 件 唤 醒 自 己。 Blocked 一 个 线 程 如 果 处 于Blocked( 堵 塞) 状 态, 那 么 暂 时 这 个 线 程 将 无 法 进 入 就 绪 队 列。 处 于 堵 塞 状 态 的 线 程 通 常 必 须 由 某 些 事 件 才 能 唤 醒。 至 于 是 何 种 事 件, 则 取 决 于 堵 塞 发 生 的 原 因: 处 于 睡 眠 中 的 线 程 必 须 被 堵 塞 一 段 固 定 的 时 间; 被 挂 起、 或 处 于 消 息 等 待 状 态 的 线 程 则 必 须 由 一 外
15、 来 事 件 唤 醒。 Dead Dead 表 示 线 程 巳 退 出 运 行 状 态, 并 且 不 再 进 入 就 绪 队 列. 其 中 原 因 可 能 是 线 程 巳 执 行 完 毕( 正 常 结 束), 也 可 能 是 该 线 程 被 另 一 线 程 所 强 行 中 断(kill)。 三、 创 建 和 使 用 线 程 的 基 本 方 法 1. 线 程 的 产 生 在Java 语 言 中, 可 采 用 两 种 方 式 产 生 线 程: 一 是 实 现 一 个Runnable 界 面, 二 是 扩 充 一 个Thread 类.java.lang 中 定 义 了 一 个 直 接 从 根 类Ob
16、ject 中 派 生 的Thread 类. 所 有 以 这 个 类 派 生 的 子 类 或 间 接 子 类, 均 为 线 程。 在 这 种 方 式 中, 需 要 作 为 一 个 线 程 执 行 的 类 只 能 继 承、 扩 充 单 一 的 父 类。 下 面 的 例 子 通 过 扩 充Thread 类, 用 该 线 程 自 己 的 实 现 来 覆 盖Thread.run(), 产 生 一 个 新 类Counter。run () 方 法 是Counter 类 线 程 所 作 的 全 部 操 作. import java.lang.*; public class Counter extends Thre