一)wait()、notify()、notifyAll()简介
void wait():使该线程处于等待状态。
void wait(long timeout):指定该线程等待的时间,以毫秒为单位。
void wait(long timeout, int nanos):指定该线程等待的时间,以毫秒+纳秒为单位。
void notify():唤醒正在等待对象监视器的单个线程。如果有多个线程,随机唤醒其中一个就绪状态的线程。
void notifyAll():唤醒正在等待对象监视器的所有线程。
线程等待:Object类中的wait()方法,使当前线程变为等待状态,直到其它线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。该两个唤醒方法也是Object类中的方法,作用等价于调用 wait(0) 一样。
线程唤醒:Object类中的notify()方法,唤醒正在等待对象监视器的单个线程。如果有多个线程都在此对象上等待,则会随机选择唤醒其中一个线程。Object类中的notifyAll()方法,唤醒正在等待对象监视器的所有线程。
二)wait()、notify()、notifyAll()
案例:建立三个线程,A线程打印10次A,B打印10次B,C打印10次C,要求线程同时运行,交替打印10次ABC。
public class PrintABC implements Runnable {
private String name;
private Object prev; // 前一个线程
private Object self; // 本身线程
public PrintABC(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}
public void run() {
int count = 0;
while (count < 10) {
synchronized(prev) {
synchronized(self) {
System.out.print(name);
count++;
self.notify(); // 把自身线程唤醒
}
try {
prev.wait(); // 前一个线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();
PrintABC pa = new PrintABC("A", c, a);
PrintABC pb = new PrintABC("B", a, b);
PrintABC pc = new PrintABC("C", b, c);
Thread ta = new Thread(pa);
ta.start();
Thread.sleep(100); // 指定睡眠时间,主要是为了交替打印ABC
Thread tb = new Thread(pb);
tb.start();
Thread.sleep(100);
Thread tc = new Thread(pc);
tc.start();
Thread.sleep(100);
}
}
运行结果:
三)为什么wait()、notify()、notifyAll()等函数定义在Object类中,而不是Thread类中
1)由于这些方法存在于同步中。使用这些方法时必须标识同步所属的锁。 锁可以是任意对象,任意对象调用方法一定定义在Object类中。
2)wait()、notify()、notifyAll()依赖于“同步锁”,而“同步锁”是由对象持有锁,并且每个对象有且仅有一个锁!这就是为什么wait()、notify()、notifyAll()等函数定义在Object类,而不是Thread类中的原因。
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!