发信人: vivian (vivid), 信区: Training
标  题: JAVA语言入门(七)
发信站: 紫 丁 香 (Sun Jan 17 18:24:07 1999), 转信

第 七 章 多 线 程 

                                   7.1 多 线 程 的 概 念 

多 线 程 编 程 的 含 义 是 你 可 将 程 序 任 务 分 成 几 个 并 行 的 子 任 务。 特 别 是 在 网 络 编 程 中, 你 会 发
现 很 多 功 能 是 可 以 并 发 执 行 的。 比 如 网 络 传 输 速 度 较 慢, 用 户 输 入 速 度 较 慢, 你 可 以 用 两 个
独 立 的 线 程 去 完 成 这 些 功 能, 而 不 影 响 正 常 的 显 示 或 其 他 功 能。 多 线 程 是 与 单 线 程 比 较 而 言
的, 普 通 的WINDOWS采 用 单 线 程 程 序 结 构, 其 工 作 原 理 是: 主 程 序 有 一 个 消 息 循 环, 不 断 从 消
息 队 列 中 读 入 消 息 来 决 定 下 一 步 所 要 干 的 事 情, 一 般 是 一 个 子 函 数, 只 有 等 这 个 子 函 数 执 行
完 返 回 后, 主 程 序 才 能 接 收 另 外 的 消 息 来 执 行。 比 如 子 函 数 功 能 是 在 读 一 个 网 络 数 据, 或 读
一 个 文 件, 只 有 等 读 完 这 些 数 据 或 文 件 才 能 接 收 下 一 个 消 息。 在 执 行 这 个 子 函 数 过 程 中 你 什
么 也 不 能 干。 但 往 往 读 网 络 数 据 和 等 待 用 户 输 入 有 很 多 时 间 处 于 等 待 状 态, 多 线 程 利 用 这 个
特 点 将 任 务 分 成 多 个 并 发 任 务 后, 就 可 以 解 决 这 个 问 题。 

                                    7.1.1 Java线 程 的 模 型 

Java的 设 计 思 想 是 建 立 在 当 前 大 多 数 操 作 系 统 都 实 现 了 线 程 调 度。Java虚 拟 机 的 很 多 任 务 都 依
赖 线 程 调 度, 而 且 所 有 的 类 库 都 是 为 多 线 程 设 计 的。 实 时 上,Java支 持Macintosh和Ms-dos 的 平 台 之
所 以 迟 迟 未 出 来 就 是 因 为 这 两 个 平 台 都 不 支 持 多 线 程。Java利 用 多 线 程 实 现 了 整 个 执 行 环 境 是
异 步 的。 在Java程 序 里 没 有 主 消 息 循 环。 如 果 一 个 线 程 等 待 读 取 网 络 数 据, 它 可 以 运 行 但 不 停
止 系 统 的 其 他 线 程 执 行。 用 于 处 理 用 户 输 入 的 线 程 大 多 时 间 是 等 待 用 户 敲 键 盘 或 击 鼠 标。 你
还 可 以 使 动 画 的 每 一 帧 之 间 停 顿 一 秒 而 并 不 使 系 统 暂 停。 一 旦 线 程 启 动 后, 它 可 以 被 挂 起,
暂 时 不 让 它 执 行。 挂 起 的 线 程 可 以 重 新 恢 复 执 行。 任 何 时 间 线 程 都 可 以 被 停 止, 被 停 止 的 线
程 就 不 能 再 重 新 启 动。 Java语 言 里, 线 程 表 现 为 线 程 类, 线 程 类 封 装 了 所 有 需 要 的 线 程 操 作 控
制。 在 你 心 里, 必 须 很 清 晰 地 区 分 开 线 程 对 象 和 运 行 线 程, 你 可 以 将 线 程 对 象 看 作 是 运 行 线
程 的 控 制 面 板。 在 线 程 对 象 里 有 很 多 函 数 来 控 制 一 个 线 程 是 否 运 行, 睡 眠, 挂 起 或 停 止。 线 程
类 是 控 制 线 程 行 为 的 唯 一 的 手 段。 一 旦 一 个Java程 序 启 动 后, 就 已 经 有 一 个 线 程 在 运 行。 你 可
通 过 调 用Thread.currentThread 函 数 来 查 看 当 前 运 行 的 是 哪 一 个 线 程。 一 旦 你 得 到 一 个 线 程 的 控 制
柄, 你 就 可 以 作 一 些 很 有 趣 的 事 情, 即 使 单 线 程 也 一 样。 下 面 这 个 例 子 让 你 知 道 怎 样 操 纵 当
前 线 程。 Filename:testthread 

class testthread { public static void main(String args[]) { Thread t =Thread.currentThread(); t.setName("This Thread is running");
System.out.println("The running thread:" + t); try { for (int i=0;i<5;i++) { System.out.println("Sleep time "+i); Thread.sleep(1000);


} catch (InterruptedException e) {System.out.println("thread has wrong"); } 

} } 

执 行 结 果:java testthread The running thread:Thread[This Thread is running,5,main] Sleep time 0 Sleep time 1 Sleep time 2
Sleep time 3 Sleep time 4 

                                        7.1.2 启 动 接 口

一 个 线 程 并 不 激 动 人 心, 多 个 线 程 才 有 实 际 意 义。 我 们 怎 样 创 建 更 多 的 线 程 呢? 我 们 需 要 创
建 线 程 类 的 另 一 个 实 例。 当 我 们 构 造 了 线 程 类 的 一 个 新 的 实 例, 我 们 必 须 告 诉 它 在 新 的 线 程
里 应 执 行 哪 一 段 程 序。 你 可 以 在 任 意 实 现 了 启 动 接 口 的 对 象 上 启 动 一 个 线 程。 启 动 接 口 是 一
个 抽 象 接 口, 来 表 示 本 对 象 有 一 些 函 数 想 异 步 执 行。 要 实 现 启 动 接 口, 一 个 类 只 需 要 有 一 个
叫run的 函 数。 下 面 是 创 建 一 个 新 线 程 的 例 子: 

Filename:twothread.java 

class twothread implements Runnable { twothread() { Thread t1 =Thread.currentThread(); t1.setName("The first main thread");
System.out.println("The running thread:" + t1); Thread t2 = new Thread(this,"the second thread"); System.out.println("creat
another thread"); t2.start(); try { System.out.println("first thread will sleep"); Thread.sleep(3000); }catch (InterruptedException e)
{System.out.println("first thread has wrong"); } System.out.println("first thread exit"); } public void run() { try { for (int
i=0;i<5;i++) { System.out.println("Sleep time for thread 2:"+i); Thread.sleep(1000); } 

} catch (InterruptedException e) {System.out.println("thread has wrong"); } 

System.out.println("second thread exit"); } public static void main(String args[]) { new twothread(); } } 

执 行 结 果:java twothread 

The running thread:Thread[The first main thread,5,main] creat another thread first thread will sleep Sleep time for thread 2:0
Sleep time for thread 2:1 Sleep time for thread 2:2 first thread exit Sleep time for thread 2:3 Sleep time for thread 2:4 second
thread exit 

main线 程 用new Thread(this, "the second thread")创 建 了 一 个Thread对 象, 通 过 传 递 第 一 个 参 数 来 标 明 新 线
程 来 调 用this对 象 的run函 数。 然 后 我 们 调 用start函 数, 它 将 使 线 程 从run函 数 开 始 执 行。 

                                          7.1.3 同 步 

因 为 多 线 程 给 你 提 供 了 程 序 的 异 步 执 行 的 功 能, 所 以 在 必 要 时 必 须 还 提 供 一 种 同 步 机 制。 例
如, 你 想 两 个 线 程 通 讯 并 共 享 一 个 复 杂 的 数 据 结 构, 你 需 要 一 种 机 制 让 他 们 相 互 牵 制 并 正 确
执 行。 为 这 个 目 的,Java用 一 种 叫 监 视 器(monitor)的 机 制 实 现 了 进 程 间 的 异 步 执 行。 可 以 将 监 视 器
看 作 是 一 个 很 小 的 盒 子, 它 只 能 容 纳 一 个 线 程。 一 旦 一 个 线 程 进 入 一 个 监 视 器, 所 有 其 他 线
程 必 须 等 到 第 一 个 线 程 退 出 监 视 器 后 才 能 进 入。 这 些 监 视 器 可 以 设 计 成 保 护 共 享 的 数 据 不 被
多 个 线 程 同 时 操 作。 大 多 数 多 线 程 系 统 将 这 些 监 视 器 设 计 成 对 象,Java提 供 了 一 种 更 清 晰 的 解
决 方 案。 没 有Monitor类; 每 个 对 象 通 过 将 他 们 的 成 员 函 数 定 义 成synchronized来 定 义 自 己 的 显 式 监
视 器, 一 旦 一 个 线 程 执 行 在 一 个synchronized函 数 里, 其 他 任 何 线 程 都 不 能 调 用 同 一 个 对 象 的
synchronized函 数。 

                                          7.1.4 消 息 

一 旦 你 的 程 序 被 分 成 几 个 逻 辑 线 程, 你 必 须 清 晰 的 知 道 这 些 线 程 之 间 应 怎 样 相 互 通 讯。Java 提
供 了wait和notify等 功 能 来 使 线 程 之 间 相 互 交 谈。 一 个 线 程 可 以 进 入 某 一 个 对 象 的synchronized 函 数
进 入 等 待 状 态, 直 到 其 他 线 程 显 式 地 将 它 唤 醒。 可 以 有 多 个 线 程 进 入 同 一 个 函 数 并 等 待 同 一
个 唤 醒 消 息。 

                                   7.2 Java线 程 例 子 

                                    7.2.1 显 式 定 义 线 程 

在 我 们 的 单 线 程 应 用 程 序 里, 我 们 并 没 有 看 见 线 程, 因 为Java能 自 动 创 建 和 控 制 你 的 线 程。 如
果 你 使 用 了 理 解Java语 言 的 浏 览 器, 你 就 已 经 看 到 使 用 多 线 程 的Java程 序 了。 你 也 许 注 意 到 两 个
小 程 序 可 以 同 时 运 行, 或 在 你 移 动 滚 动 条 时 小 程 序 继 续 执 行。 这 并 不 是 表 明 小 程 序 是 多 线 程
的, 但 说 明 这 个 浏 览 器 是 多 线 程 的。 多 线 程 应 用 程 序(或applet)可 以 使 用 好 几 个 执 行 上 下 文 来 完
成 它 们 的 工 作。 多 线 程 利 用 了 很 多 任 务 包 含 单 独 的 可 分 离 的 子 任 务 的 特 点。 每 一 个 线 程 完 成
一 个 子 任 务。 

但 是, 每 一 个 线 程 完 成 子 任 务 时 还 是 顺 序 执 行 的。 一 个 多 线 程 程 序 允 许 各 个 线 程尽快 执 行 完 它
们。 这 种 特 点 会 有 更 好 的 实 时 输 入 反 应。 

                                      7.2.2 多 线 程 例 子

下 面 这 个 例 子 创 建 了 三 个 单 独 的 线 程, 它 们 分 别 打 印 自 己 的“Hello World": 

//Define our simple threads.They will pause for a short time //and then print out their names and delay times class TestThread
extends Thread { private String whoami; private int delay; 

//Our constructor to store the name (whoami) //and time to sleep (delay) public TestThread(String s, int d) { whoami = s; delay =
d; } 

//Run - the thread method similar to main() //When run is finished, the thread dies. //Run is called from the start() method of
Thread public void run() { //Try to sleep for the specified time try { sleep(delay); } catch(InterruptedException e) {} //Now print
out our name System.out.println("Hello World!"+whoami+""+delay); } } /** * Multimtest. A simple multithread thest program */
public class multitest { public static void main(String args[]) { TestThread t1,t2,t3; //Create our test threads t1 = new
TestThread("Thread1",(int)(Math.readom()*2000)); t2 = new TestThread("Thread2",(int)(Math.readom()*2000)); t3 = new
TestThread("Thread3",(int)(Math.readom()*2000)); 

//Start each of the threads t1.start(); t2.start(); t3.start(); } } 

                                    7.2.3 启 动 一 个 线 程 

程 序 启 动 时 总 是 调 用main()函 数, 因 此main()是 我 们 创 建 和 启 动 线 程 的 地 方: 

t1 = new TestThread("Thread1",(int)(Math.readom()*2000)); 

这 一 行 创 建 了 一 个 新 的 线 程。 后 面 的 两 个 参 数 传 递 了 线 程 的 名 称 和 线 程 在 打 印 信 息 之 前 的 延
时 时 间。 因 为 我 们 直 接 控 制 线 程, 我 们 必 须 直 接 启 动 它: t1.start(); 

                                       7.2.4 操 作 线 程 

如 果 创 建 线 程 正 常,t1应 包 含 一 个 有 效 的 执 行 线 程。 我 们 在 线 程 的run()函 数 里 控 制 线 程。 一 旦 我
们 进 入run()函 数, 我 们 便 可 执 行 里 面 的 任 何 程 序。run()好 象main()一 样。 一 旦run() 执 行 完, 这 个 线 程
也 就 结 束 了。 在 这 个 例 子 里, 我 们 试 着 延 迟 一 个 随 机 的 时 间(通 过 参 数 传 递): sleep(delay); 

sleep()函 数 只 是 简 单 地 告 诉 线 程 休 息 多 少 个 毫 秒 时 间。 如 果 你 想 推 迟 一 个 线 程 的 执 行, 你 应 使
用sleep()函 数。 当 线 程 睡 眠 是sleep()并 不 占 用 系 统 资 源。 其 它 线 程 可 继 续 工 作。 一 旦 延 迟 时 间 完
毕, 它 将 打 印"Hello World"和 线 程 名 称 及 延 迟 时 间。 

                                    7.2.5 暂 停 一 个 线 程 

我 们 经 常 需 要 挂 起 一 个 线 程 而 不 指 定 多 少 时 间。 例 如, 如 果 你 创 建 了 一 个 含 有 动 画 线 程 的 小
程 序。 也 许 你 让 用 户 暂 停 动 画 至 到 他 们 想 恢 复 为 止。 你 并 不 想 将 动 画 线 程 仍 调, 但 想 让 它 停
止。 象 这 种 类 似 的 线 程 你 可 用suspend()函 数 来 控 制: t1.suspend(); 

这 个 函 数 并 不 永 久 地 停 止 了 线 程, 你 还 可 用resume()函 数 重 新 激 活 线 程: t1.resume(); 

                                    7.2.6 停 止 一 个 线 程 

线 程 的 最 后 一 个 控 制 是 停 止 函 数stop()。 我 们 用 它 来 停 止 线 程 的 执 行: t1.stop(); 

注 意: 这 并 没 有 消 灭 这 个 线 程, 但 它 停 止 了 线 程 的 执 行。 并 且 这 个 线 程 不 能 用t1.start()重 新 启
动。 在 我 们 的 例 子 里, 我 们 从 来 不 用 显 式 地 停 止 一 个 线 程。 我 们 只 简 单 地 让 它 执 行 完 而 已。 很
多 复 杂 的 线 程 例 子 将 需 要 我 们 控 制 每 一 个 线 程。 在 这 种 情 况 下 会 使 用 到stop()函 数。 如 果 需 要,
你 可 以 测 试 你 的 线 程 是 否 被 激 活。 一 个 线 程 已 经 启 动 而 且 没 有 停 止 被 认 为 是 激 活 的。 t1.isAlive()
如 果t1是 激 活 的, 这 个 函 数 将 返 回true. 

                                       7.2.7 动 画 例 子 

下 面 是 一 个 包 含 动 画 线 程 的applet例 子: 

import java.awt.*; import java.awt.image.ImageProducer; import java.applet.Applet; 

public class atest3 extends Applet implements Runnable { Image images[]; MediaTracker tracker; int index = 0; Thread animator;

int maxWidth,maxHeight; //Our off-screen components for double buffering. Image offScrImage; Graphics offScrGC; 

//Can we paint yes? boolean loaded = false; 

//Initialize the applet. Set our size and load the images public void init() [ //Set up our image monitor tracker = new
MediaTracker(this); 

//Set the size and width of our applet maxWidth = 100; maxHeight =100; 

images = new Image[10]; //Set up the double-buffer and resize our applet try { offScrImage =
createImage(maxWidth,maxHeight); offScrGC = offScrImage.getGraphics(); offScrGC.setColor(Color.lightGray);
offScrGC.fillRect(0,0,maxWidth,maxHeight); resize(maxWidth,maxHeight); }catch (Exception e) { e.printStackTrace(); } 

//load the animation images into an array for (int i=0;i<10;i++) { String imageFile = new String ("images/Duke/T"
+String.valueOf(i+1) +".gif"); images[i] = getImage(getDocumentBase(),imageFile): //Register this image with the tracker
tracker.addImage(images[i],i); } try { //Use tracker to make sure all the images are loaded tracker.waitForAll(); } catch
(InterruptedException e) {} loaded = true; } 

//Paint the current frame. public void paint (Graphics g) { if (loaded) { g.drawImage(offScrImage,0,0,this); } } 

//Start ,setup our first image public void start() { if (tracker.checkID (index)) { offScrGC.drawImage (images[index],0,0,this); }
animator = new Thread(this); animator.start(); } 

//Run,do the animation work here. //Grab an image, pause ,grab the next... public void run() { //Get the id of the current thread
Thread me = Thread.currentThread(); 

//If our animator thread exist,and is the current thread... while ((animatr!= null) && (animator==me)) { if ( tracker.checkID
(index)) { //Clear the background and get the next image offScrGC.fillRect(0,0,100,100);
offScrGCdrawImage(images[index],0,0,this); index++; //Loop back to the beginning and keep going if (index>= images.length) {
index = 0; } } //Delay here so animation looks normal try { animator.sleep(200); }catch (InterruptedException e) {} //Draw the
next frame repaint(); } } } 

                               7.3 多 线 程 之 间 的 通 讯

                                   7.3.1 生 产 者 和 消 费 者 

多 线 程 的 一 个 重 要 特 点 是 它 们 之 间 可 以 互 相 通 讯。 你 可 以 设 计 线 程 使 用 公 用 对 象, 每 个 线 程
都 可 以 独 立 操 作 公 用 对 象。 典 型 的 线 程 间 通 讯 建 立 在 生 产 者 和 消 费 者 模 型 上: 一 个 线 程 产 生
输 出; 另 一 个 线 程 使 用 输 入。 

buffer 

让 我 们 创 建 一 个 简 单 的"Alphabet Soup"生 产 者 和 相 应 的 消 费 者. 

                                         7.3.2 生 产 者 

生 产 者 将 从thread类 里 派 生: class Producer extends Thread { private Soup soup; private String alphabet = "
ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 

public Producer(Soup s) { //Keep our own copy of the shared object soup = s; } 

public void run() { char c; //Throw 10 letters into the soup for (int i=0;i<10;i++) { c = alphabet.charAt((int)(Math.random() *26));
soup.add(c); //print a record of osr addition System.out.println("Added"+c + "to the soup."); //wait a bit before we add the next
letter try { sleep((int)(Math.random() *1000)); } catch (InterruptedException e) {} } } } 

注 意 我 们 创 建 了Soup类 的 一 个 实 例。 生 产 者 用soup.add()函 数 来 建 立 字 符 池。 

                                         7.3.3 消 费 者

让 我 们 看 看 消 费 者 的 程 序: class Consumer extends Thread { private Soup soup; 

public Consumer (Soup s) { //keep our own copy of the shared object soup = s; } 

public void run() { char c; //Eat 10 letters from the alphabet soup for (int I=0 ;i<10;i++) { //grab one letter c = soup.eat(); //Print
out the letter that we retrieved System.out.println("Ate a letter: " +c); //try { sleep((int)(Math.raddom()*2000)); } catch
(InterruptedException e) {} } } } 

同 理, 象 生 产 者 一 样, 我 们 用soup.eat()来 处 理 信 息。 那 么,Soup类 到 底 干 什 么 呢? 

                                          7.3.4 监 视 

Soup类 执 行 监 视 两 个 线 程 之 间 传 输 信 息 的 功 能。 监 视 是 多 线 程 中 不 可 缺 少 的 一 部 分, 因 为 它 保
持 了 通 讯 的 流 畅。 让 我 们 看 看Soup.java文 件: class Soup { private char buffer[] = new char[6]; private int next = 0;
//Flags to keep track of our buffer status private boolean isFull = false; private boolean isEmpty = true; 

public syschronized char eat() { //We can't eat if there isn't anything in the buffer while (isEmpty == true) { try { wait() ;//we'll
exit this when isEmpty turns false }catch (InterruptedException e) {} } //decrement the count,since we're going to eat one letter
next--; //Did we eat the last letter? if (next== 0) { isEmpty = true; } //We know the buffer can't be full,because we just ate isFull
= false; notify(); //return the letter to the thread that is eating return (buffer[next]); } 

//method to add letters to the buffer public synchronized void add(char c) { //Wait around until there's room to add another letter
while (isFull == true ) { try{ wait();//This will exit when isFull turns false }catch (InterruptedException e) {} } //add the letter to
the next available spot buffer[next]=c; //Change the next available spot next++; //Are we full; if (next ==6) { isFull =true; }
isEmpty =false; notify(); } } 

soup类 包 含 两 个 重 要 特 征: 数 据 成 员buffer[]是 私 有 的, 功 能 成 员add()和eat()是 公 有 的。 

数 据 私 有 避 免 了 生 产 者 和 消 费 者 直 接 获 得 数 据。 直 接 访 问 数 据 可 能 造 成 错 误。 例 如, 如 果 消
费 者 企 图 从 空 缓 冲 区 里 取 出 数 据, 你 将 得 到 不 必 要 的 异 常, 否 则, 你 只 能 锁 住 进 程。 同 步 访 问
方 法 避 免 了 破 坏 一 个 共 享 对 象。 当 生 产 者 向soup里 加 入 一 个 字 母 时, 消 费 者 不 能 吃 字 符, 诸 如
此 类。 这 种 同 步 是 维 持 共 享 对 象 完 整 性 的 重 要 方 面。notify()函 数 将 唤 醒 每 一 个 等 待 线 程。 等 待
线 程 将 继 续 它 的 访 问。 

                                       7.3.5 联 系 起 来 

现 在 我 们 有 一 个 生 产 者, 一 个 消 费 者 和 一 个 共 享 对 象, 怎 样 实 现 它 们 的 交 互 呢? 我 们 只 需 要
一 个 简 单 的 控 制 程 序 来 启 动 所 有 的 线 程 并 确 信 每 一 个 线 程 都 是 访 问 的 同 一 个 共 享 对 象。 下 面
是 控 制 程 序 的 代 码,SoupTest.java: class SoupTest { public static void main(String args[]) { Soup s = new Soup();
Producer p1 = new Producer(s); Consumer c1 = new Consumer(s); 

p1.start(); c1.start(); } } 

                                      7.3.6 监 视 生 产 者 

生 产 者/消 费 者 模 型 程 序 经 常 用 来 实 现 远 程 监 视 功 能, 它 让 消 费 者 看 到 生 产 者 同 用 户 的 交 互 或
同 系 统 其 它 部 分 的 交 互。 例 如, 在 网 络 中, 一 组 生 产 者 线 程 可 以 在 很 多 工 作 站 上 运 行。 生 产 者
可 以 打 印 文 档, 文 档 打 印 后, 一 个 标 志 将 保 存 下 来。 一 个(或 多 个) 消 费 者 将 保 存 标 志 并 在 晚
上 报 告 白 天 打 印 活 动 的 情 况。 另 外, 还 有 例 子 在 一 个 工 作 站 是 分 出 几 个 独 立 的 窗 口。 一 个 窗
口 用 作 用 户 输 入(生 产 者), 另 一 个 窗 口 作 出 对 输 入 的 反 应(消 费 者)。 

                                    7.4 线 程API列 表 

下 面 是 一 些 常 用 的 线 程 类 的 方 法 函 数 列 表: 

类 函 数: 以 下 是Thread的 静 态 函 数, 即 可 以 直 接 从Thread类 调 用。 

currentThread 返 回 正 在 运 行 的Thread对 象 yield 停 止 运 行 当 前 线 程, 让 系 统 运 行 下 一 个 线 程 sleep(int n)
让 当 前 线 程 睡 眠n毫 秒 

对 象 函 数: 以 下 函 数 必 须 用Thread的 实 例 对 象 来 调 用。 

start start函 数 告 诉java运 行 系 统 为 本 线 程 建 立 一 个 执 行 环 境, 然 后 调 用 本 线 程 的run()函 数。 run 是 运
行 本 线 程 的 将 要 执 行 的 代 码, 也 是Runnable接 口 的 唯 一 函 数。 当 一 个 线 程 初 始 化 后, 由start函 数 来
调 用 它, 一 旦run函 数 返 回, 本 线 程 也 就 终 止 了。 stop 让 某 线 程 马 上 终 止, 系 统 将 删 除 本 线 程 的
执 行 环 境 suspend 与stop函 数 不 同,suspend将 线 程 暂 停 执 行, 但 系 统 不 破 坏 线 程 的 执 行 环 境, 你 可
以 用resume来 恢 复 本 线 程 的 执 行 resume 恢 复 被 挂 起 的 线 程 进 入 运 行 状 态 setPriority(int p) 给 线 程 设 置
优 先 级 getPriority 返 回 线 程 的 优 先 级 setName(String name) 给 线 程 设 置 名 称 getName 取 线 程 的 名 称 

                                       本 章 小 结: 

1.多 线 程 是java语 言 的 重 要 特 点,java语 言 用Thread类 封 装 了 线 程 的 所 有 操 作。 2.线 程 的 接 口 名
为Runnable 3.线 程 之 间 同 步 机 制 为synchronized关 键 词 4.线 程 之 间 通 讯 靠wait与notify消 息 


--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.243.11]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:204.343毫秒