认识wait()和notify() 博客分类: J2SE IEthreadJ2SE
本文用一个【做饭者】和一个【打扫者】并发访问【卫生间】的例子来探讨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 |