Java编程思想第4版[中文版](PDF格式)-第133部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
一样会产生同样的 IllegalMonitorStateException违例。我们没办法用其他人的对象锁来愚弄系统,但可要
求另一个对象执行相应的操作,对它自己的锁进行操作。所以一种做法是创建一个同步方法,令其为自己的
对象调用notify() 。但在Notifier 中,我们会看到一个同步方法内部的notify() :
synchronized(wn2) {
wn2。notify();
}
其中,wn2 是类型为WaitNotify2 的对象。尽管并不属于WaitNotify2 的一部分,这个方法仍然获得了wn2
对象的锁定。在这个时候,它为wn2 调用notify() 是合法的,不会得到 IllegalMonitorStateException违
例。
///:Continuing
/////////// Blocking via wait() ///////////
class WaitNotify1 extends Blockable {
public WaitNotify1(Container c) { super(c); }
public synchronized void run() {
while(true) {
i++;
update();
try {
wait(1000);
} catch (InterruptedException e){}
}
514
…………………………………………………………Page 516……………………………………………………………
}
}
class WaitNotify2 extends Blockable {
public WaitNotify2(Container c) {
super(c);
new Notifier(this);
}
public synchronized void run() {
while(true) {
i++;
update();
try {
wait();
} catch (InterruptedException e){}
}
}
}
class Notifier extends Thread {
private WaitNotify2 wn2;
public Notifier(WaitNotify2 wn2) {
this。wn2 = wn2;
start();
}
public void run() {
while(true) {
try {
sleep(2000);
} catch (InterruptedException e){}
synchronized(wn2) {
wn2。notify();
}
}
}
} ///:Continued
若必须等候其他某些条件(从线程外部加以控制)发生变化,同时又不想在线程内一直傻乎乎地等下去,一
般就需要用到wait()。wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变。而
且只有在一个notify()或 notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变。因此,我
们认为它提供了在线程间进行同步的一种手段。
4。 IO 堵塞
若一个数据流必须等候一些 IO活动,便会自动进入“堵塞”状态。在本例下面列出的部分中,有两个类协同
通用的 Reader 以及Writer 对象工作(使用Java 1。1 的流)。但在测试模型中,会设置一个管道化的数据
流,使两个线程相互间能安全地传递数据(这正是使用管道流的目的)。
Sender 将数据置入 Writer,并“睡眠”随机长短的时间。然而,Receiver 本身并没有包括 sleep(),
suspend()或者wait()方法。但在执行read()的时候,如果没有数据存在,它会自动进入“堵塞”状态。如
下所示:
///:Continuing
class Sender extends Blockable { // send
515
…………………………………………………………Page 517……………………………………………………………
private Writer out;
public Sender(Container c; Writer out) {
super(c);
this。out = out;
}
public void run() {
while(true) {
for(char c = 'A'; c