這個三個函數來自Object類,眾所周知它們是用於多線程同步的。
然而,有個問題卻一直沒搞清楚,即notify()函數到底通知誰?
《Thinking in JAVA》中有這么一句話,當notify()函數因為某個特定鎖被調用時,只有等待
這個鎖的任務才會被喚醒。
什么意思?
看下面的代碼,這個代碼執行的話會報錯,java.lang.IllegalMonitorStateException
上網查了一下,明白了。
1>當前線程不含有當前對象的鎖資源的時候,調用obj.wait()方法;
2>當前線程不含有當前對象的鎖資源的時候,調用obj.notify()方法。
3>當前線程不含有當前對象的鎖資源的時候,調用obj.notifyAll()方法。
public class Apple implements Runnable{ public static Object apple=new Object(); @Override public void run() { synchronized(apple) { System.out.println("apple locked"); try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("apple run end"); } }
把上面代碼的 synchronized(apple)
改為 synchronized(this)就不報錯類
原來,只有當前線程擁有了對象A的鎖的時候,才能在A上調用wait函數,那么,此時,這個線程就是
在對象A上等待。
如果其他線程調用類A.notify(),那么在A上等待的線程就會醒來。
那么還有個問題,因為notify函數的調用也需要獲取該對象的鎖,而wait已經取得了這個鎖,那么豈不是自相矛盾了?
原來在進入wait()函數之后,線程會自動的把自己擁有的所有鎖都釋放掉。這樣其他線程就可以重新獲得這些鎖,利用
這些鎖做一些事,使得某些條件得到滿足之后再通知之前wai的線程。