⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 7.html

📁 这是介绍JAVE 语言的书籍
💻 HTML
📖 第 1 页 / 共 2 页
字号:
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 多 线 程 ?reg; 间 的 通 讯
7.3.1 生 产 者 和 消 费 者 
多 线 程 的 一 个 重 要 特 点 是 它 们 ?reg; 间 可 以 互 相 通 讯。 你 
可 以 设 计 线 程 使 用 公 用 对 象, 每 个 线 程 都 可 以 独 立 操 作 
公 用 对 象。 典 型 的 线 程 间 通 讯 建 立 在 生 产 者 和 消 费 者 模 
型 上: 一 个 线 程 产 生 输 出; 另 一 个 线 程 使 用 输 入。 
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类 执 行 监 视 两 个 线 程 ?reg; 间 传 输 信 息 的 功 能。 监 视 
是 多 线 程 中 不 可 缺 少 的 一 部 分, 因 为 它 保 持 了 通 讯 的 
流 ?copy;。 让 我 们 看 看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 监 视 生 产 者 
生 产 者/消 费 者 模 型 程 序 经 常 用 来 实 现 远 程 监 视 功 能, 它 
让 消 费 者 看 到 生 产 者 同 用 户 的 交 互 或 同 系 统 其 它 部 分 
的 交 互。 例 如, 在 网 络 中, 一 组 生 产 者 线 程 可 以 在 很 多 工 
作 站 上 运 行。 生 产 者 可 以 打 印 文 档, 文 档 打 印 后, 一 个 标 
志 将 保 存 下 来。 一 个(或 多 个?copy; 消 费 者 将 保 存 标 志 并 在 
晚 上 报 告 白 天 打 印 活 动 的 情 况。 另 外, 还 有 例 子 在 一 个 
工 作 站 是 分 出 几 个 独 立 的 窗 口。 一 个 窗 口 用 作 用 户 输 入
(生 产 者?copy;, 另 一 个 窗 口 作 出 对 输 入 的 反 应(消 费 
者?copy;。 
7.4 线 程API列 表 
下 面 是 一 ?copy; 常 用 的 线 程 类 的 方 法 函 数 列 表: 
类 函 数: 以 下 是Thread的 静 态 函 数, 即 可 以 直 接 从Thread类 调 
用。 
currentThread 返 回 正 在 运 行 的Thread对 象 yield 停 止 运 行 当 
前 线 程, 让 系 统 运 行 下 一 个 线 程 sleep(int n) 让 当 前 线 程 
睡 眠n毫 秒 
对 象 函 数: 以 下 函 数 必 须 用Thread的 实 例 对 象 来 调 用。 
start start函 数 告 诉java运 行 系 统 为 本 线 程 建 立 一 个 执 行 
环 境, 然 后 调 用 本 线 程 的run()函 数。 run 是 运 行 本 线 程 的 
将 要 执 行 的 代 码, 也 是Runnable接 口 的 唯 一 函 数。 当 一 个 线 
程 初 始 化 后, 由start函 数 来 调 用 它, 一 ?copy;run函 数 返 回, 
本 线 程 也 就 终 止 了。 stop 让 某 线 程 马 上 终 止, 系 统 将 删 除 
本 线 程 的 执 行 环 境 suspend 与stop函 数 不 同,suspend将 线 程 暂 
停 执 行, 但 系 统 不 破 坏 线 程 的 执 行 环 境, 你 可 以 用resume
来 恢 复 本 线 程 的 执 行 resume 恢 复 被 挂 起 的 线 程 进 入 运 行 
状 态 setPriority(int p) 给 线 程 设 置 优 先 级 getPriority 返 回 线 
程 的 优 先 级 setName(String name) 给 线 程 设 置 名 称 getName 取 
线 程 的 名 称 
本 章 小 结: 
1.多 线 程 是java语 言 的 重 要 特 点,java语 言 用Thread类 封 装 了 
线 程 的 所 有 操 作。 2.线 程 的 接 口 名 为Runnable 3.线 程 ?reg; 间 
同 步 机 制 为synchronized关 键 词 4.线 程 ?reg; 间 通 讯 靠wait与
notify消 息 

</pre></div></td></tr></table><hr width=90% color=#7A7A71><!--end_content-->      <br>    </TD>    <TD bgColor=#c6bba4 vAlign=top width="1%"></TD>    <TD bgColor=#c6bba4 vAlign=bottom width="11%"><b><a href="/index.html">回首页</a><br><br><a href='6.html'>上一页</a><br><br><a href='8.html'>下一页</a><br><br><a href='http://pub.goldnets.com:81/bbs/post.php?job=new&topic=12210' target=_blank> 我有话说 </a><br><br><a href='http://pub.goldnets.com:81/bbs/bbslist.php?topic=12210' target=_blank> 评论一览 </a></center><br><!--title_end1--></b><br></TD>  </TR></TABLE><TABLE background=images/bj.jpg border=0 cellSpacing=0 width="100%">  <TR>    <TD bgColor=#c6bba4 vAlign=top width="12%">&nbsp;</TD>    <TD background=/images/bj.jpg vAlign=top width="76%">    <br>    <center>      <iframe width=468 height=60 marginwidth=0 marginheight=0 hspace=0 vspace=0 frameborder=0 scrolling=no bordercolor="#000000" src="/banner4.html"></iframe>    </center>    <center>      <script language="JavaScript" src="http://www.myrice.com/bottom.js"></script>    </center>    </TD>    <TD bgColor=#c6bba4 vAlign=top width="12%" align="left"></TD>  </TR></TABLE><center>  <script language="JavaScript" src="/bottom.js"></script></center></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -