wait()方法作用:
调用wait()方法后,当前线程休眠,且释放其占有的对象锁。
notify()方法作用:
调用notify()方法后,唤醒一个正在等待当前对象锁的线程,赋予其对象锁。
notify All()方法作用:
调用notify()方法后,唤醒所有正在等待当前对象锁的线程。
以上三个方法均为Object类的方法,可以用于多线程。并且在调用这3个方法的时候,当前线程必须获得这个对象(Object)的锁。
多个线程都持有同一个对象的时候,如果都要进入synchronized(obj){......}的内部,就必须拿到这个对象的锁。
synchronized的机制保证了同一时间最多只能有1个线程拿到了对象的锁。
以下为一个小栗子
建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。
public class MyThreadPrinter implements Runnable {
private String name;
private Object prev;
private Object self;
private MyThreadPrinter(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}
@Override
public void run() {
int count = 10;
while (count > 0) {
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 Exception {
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThreadPrinter pa = new MyThreadPrinter2("A", c, a);
MyThreadPrinter pb = new MyThreadPrinter2("B", a, b);
MyThreadPrinter pc = new MyThreadPrinter2("C", b, c);
new Thread(pa).start();
Thread.sleep(100); //确保按顺序A、B、C执行
new Thread(pb).start();
Thread.sleep(100);
new Thread(pc).start();
Thread.sleep(100);
}
}
其中,每个线程都有prev、self两个锁。以A开始,A必须获得prev(=c)和self(=a),才能打印;当打印完A后,唤醒一个正在等待锁self(=a)的线程,这里,B在等待锁a,所以B被唤醒,B现在获得锁prev=a和self=b,所以打印B;当打印完B后,唤醒一个正在等待锁self(=b)的线程,这里,C在等待b,所以C被唤醒,C获得了锁,被打印。
如此下去即可按顺序交替打印ABC。