wait()和notify()函数属于Object类,也就是说所有的对象都拥有这两个函数。
wait()我们可以理解为等待的意思,即等待锁的释放。引用说明文档的话“Causes the current thread to wait until another thread invokes the notify()
method or the notifyAll()
method for this object.”,那就是等待着别的线程的notify()操作后本线程wait()后的代码才会被执行(wait取消了阻塞状态)。
但是notify()并不一定会使得这一个wait()取消阻塞,notify()只是令一个wait()取消阻塞,如果同一时刻有多个线程采用同一个Object进入wait()状态,哪个线程取消阻塞状态由JVM决定。如果要所有采用了同一个Object的wait()取消阻塞,那么可以采用notifyAll(),必须注意的是,上面说的这些wait都是用同一个Object加锁的。
另外要提到一点,wait()和notify()操作前要使用synchronized(obj),不然会报java.lang.IllegalMonitorStateException错误。
下面是代码:
class Test {
public static void main(String[] args) {
Object obj = new Object();
new myThread(obj).start();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("ok");
}
}
}
class myThread extends Thread {
Object obj;
public myThread(Object obj) {
// TODO Auto-generated constructor stub
this.obj = obj;
}
@Override
public void run() {
synchronized (obj) {
// TODO Auto-generated method stub
try {
sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
obj.notify();
}
}
}
10S后才打印ok。
要注意的是,notify()必须要在wait()之后调用,不然会造成wait()永久阻塞。上面的代码之所以会成功运行,是因为调用了
new myThread(obj).start();
之后新线程并不一定马上运行,所以run方面可能还没运行,因此nitify()位于wait()之后执行。严格来说,上面的这段代码是非常危险的,仅限于说明用。