Java的notify()和wait()
作为线程间通信很重要的机制,wait()和notify()函数想必大家都是很熟悉的,但是今天阅读Object源码的时候碰到这样一件有趣的事情:/**
* Causes a thread which is waiting on this object's monitor (by means of
* calling one of the {@code wait()} methods) to be woken up. If more than
* one thread is waiting, one of them is chosen at the discretion of the
* VM. The chosen thread will not run immediately. The thread
* that called {@code notify()} has to release the object's monitor first.
* Also, the chosen thread still has to compete against other threads that
* try to synchronize on the same object.
* <p>
* This method can only be invoked by a thread which owns this object's
* monitor. A thread becomes owner of an object's monitor
* </p>
* <ul>
* <li>by executing a synchronized method of that object;</li>
* <li>by executing the body of a {@code synchronized} statement that
* synchronizes on the object;</li>
* <li>by executing a synchronized static method if the object is of type
* {@code Class}.</li>
* </ul>
*
* @see #notifyAll
* @see #wait()
* @see #wait(long)
* @see #wait(long,int)
* @see java.lang.Thread
*/
public final native void notify();
可以看到这样一句话,notify()并不会使得调用相应wait()函数的线程立即执行,而是要等到调用notify()函数的线程释放掉相应的监视器占用,而且即使这样,它也可能需要和其他线程继续竞争相应的监视器,我们可以构造如下进行验证:
public class Test {
public static void main(String[] args) throws InterruptedException {
final Integer tp = 0;
final long start = System.currentTimeMillis();
Thread aThread = new Thread() {
public void run() {
synchronized (tp) {
try {
tp.wait();
System.out.println("" + (System.currentTimeMillis() - start));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
};
Thread bThread = new Thread() {
public void run() {
synchronized (tp) {
try {
tp.notify();
System.out.println("" + (System.currentTimeMillis() - start));
sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
};
aThread.start();
bThread.start();
aThread.join();
bThread.join();
}
}
结果为: 0 5001,可以很清晰的理解这个东西了。