欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

认识wait()和notify() 博客分类: J2SE IEthreadJ2SE 

程序员文章站 2024-03-18 21:42:22
...

本文用一个【做饭者】和一个【打扫者】并发访问【卫生间】的例子来探讨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

相关标签: IE thread J2SE