本文用一个【做饭者】和一个【打扫者】并发访问【卫生间】的例子来探讨Object.wait()和Object.notify()的用法。
wait()和notify()的涵义:
1、必须在synchronized 块中
2、这两个方法属于Object对象,而不是属于线程,这一点不要混淆了
3、wait()的对象是当前线程;notify()的调用者是当前线程,操作对象是正在wait的线程。
package org.eleaf.j2se.th;
import java.io.PrintStream;
public class ThreadTest2 {
public static void main(String[] args) {
Tt2Wc tw = new Tt2Wc();
Tt2Cook tc = new Tt2Cook(tw);
Tt2Sweep ts = new Tt2Sweep(tw);
Thread t1 = new Thread(tc, tc. name );
Thread t2 = new Thread(ts, ts. name );
t1.start();
t2.start();
}
}
// 卫生间
class Tt2Wc {
// 假设做饭和打扫卫生都要用到卫生间的水。
boolean isWaterOpened = false ;
// 使用卫生间
public void useWc( int sc) throws InterruptedException {
Thread t = Thread.currentThread ();
// 这段代码使得两个线程在控制台打印信息的颜色不同。其中 “ 打扫者 ” 打印信息显示为红色。
PrintStream pw = null ;
if ( " 打扫者 " .equals(t.getName())){
pw = System. err ;
} else {
pw = System. out ;
}
// 如果卫生间的水已经有人在用,就在门外等待。
if ( isWaterOpened ){
pw.println(Thread.currentThread ().getName() + " 在卫生间外面等候 " );
synchronized ( this ) {
wait();
}
}
synchronized ( this ) {
changeWaterState();
pw.println(t.getName() + " 现在使用卫生间 . 持续 " + sc/1000 + " 秒 " );
// 用 sleep() 方法来简化使用卫生间的过程。
Thread.sleep (sc);
pw.println(t.getName() + " 使用卫生间结束 ." );
changeWaterState();
// 通知在门外等待的人可以进来用水了。
notify();
}
}
private void changeWaterState() {
isWaterOpened = ! isWaterOpened ;
// System.out.println("water state:" + isWaterOpened);
}
}
// 做饭
class Tt2Cook implements Runnable {
private Tt2Wc tw ;
public String name = " 做饭者 " ;
public Tt2Cook(Tt2Wc tw){
this . tw = tw;
}
public void run(){
try {
System. out .println( name + " 开始了 ..." );
// 使用卫生间
tw .useWc(10000);
System. out .println( name + " 去忙别的事了 ++++++." );
tw .useWc(12000);
System. out .println( name + " 去忙别的事了 ++++++." );
tw .useWc(11000);
System. out .println( name + " 去忙别的事了 ++++++." );
tw .useWc(11000);
System. out .println( name + " 关闭 ." );
} catch (InterruptedException ie){
ie.printStackTrace();
}
}
}
// 打扫卫生
class Tt2Sweep implements Runnable {
public String name = " 打扫者 " ;
private Tt2Wc tw ;
public Tt2Sweep(Tt2Wc tw){
this . tw = tw;
}
public void run() {
try {
// 打扫者信息显示为红色 //
System. err .println( name + " 开始了 ..." );
// 使用卫生间
tw .useWc(10000);
System. err .println( name + " 去忙别的事了 ++++++." );
tw .useWc(10000);
System. err .println( name + " 去忙别的事了 ++++++." );
tw .useWc(10000);
System. err |