http://chenjianjx.javaeye.com/blog/230465
附:
java,wait與notify的區(qū)別
wait與notify是java同步機(jī)制中重要的組成部分。結(jié)合與synchronized關(guān)鍵字使用,可以建立很多優(yōu)秀的同步模型。
synchronized(this){}等價與public synchronized void method(){.....}
同步分為類級別和對象級別,分別對應(yīng)著類鎖和對象鎖。類鎖是每個類只有一個,如果static的方法被synchronized關(guān)鍵字修飾,則在這個方法被執(zhí)行前必須獲得類鎖;對象鎖類同。(static synchronized是類級別的,非static的synchronized和synchronized塊都是對象級別的,即作用在同一new出來的對象上)
首先,調(diào)用一個Object的wait與notify/notifyAll的時候,必須保證調(diào)用代碼對該Object是同步的,也就是說必須在作用等同于synchronized(obj){......}的內(nèi)部才能夠去調(diào)用obj的wait與notify/notifyAll三個方法,否則就會報錯:
java.lang.IllegalMonitorStateException: current thread not owner
在調(diào)用wait的時候,線程自動釋放其占有的對象鎖,同時不會去申請對象鎖。當(dāng)線程被喚醒的時候,它才再次獲得了去獲得對象鎖的權(quán)利。
所以,notify與notifyAll沒有太多的區(qū)別,只是notify僅喚醒一個線程并允許它去獲得鎖,notifyAll是喚醒所有等待這個對象的線程并允許它們?nèi)カ@得對象鎖,只要是在synchronied塊中的代碼,沒有對象鎖是寸步難行的。其實(shí)喚醒一個線程就是重新允許這個線程去獲得對象鎖并向下運(yùn)行。 順便說一下notifyall,雖然是對每個wait的對象都調(diào)用一次notify,但是這個還是有順序的,每個對象都保存這一個等待對象鏈,調(diào)用的順序就是這個鏈的順序。其實(shí)啟動等待對象鏈中各個線程的也是一個線程,在具體應(yīng)用的時候,需要注意一下。