等待方遵循的原則: 獲取對象的鎖,不滿足條件就調用wait()方法,條件滿足繼續執行
通知方原則: 獲取對象的鎖,改變條件,然后notify
每個對象都有一個監視器鎖,這個監視器鎖的數據結構如下:

wait()/notify()方法定義在Object類中。如果線程要調用對象的wait()方法,必須首先獲得該對象的監視器鎖,調用wait()之后,當前線程又立即釋放掉鎖,線程隨后進入WAIT_SET(等待池)中。如果線程要調用對象的notify()/notifyAll()方法,也必須先獲得對象的監視器鎖,調用方法之后,立即釋放掉鎖,然后處於Wait_set的線程被轉移到Entry_set(等鎖池)中,去競爭鎖資源。The Winner Thread,也就是成功獲得了對象的鎖的線程,就是對象鎖的擁有者,會進入runnable狀態。由於需要獲得鎖之后才能夠調用wait()/notify()方法,因此必須將它們放到同步代碼塊中。
正如wait方法的注釋所說:
This method should only be called by a thread that is the owner of this object's monitor
IllegalMonitorStateException if the current thread is not the owner of the object's monitor.
