-Object類中有五個關于線程的方法:三個重載的wait()方法和notify()、notifyAll()問題1:為什么這些方法不定義在Thread類里面作為靜態方法使用?而是在Object類里面?這個問題先放下,先看線程狀態圖:new出一個線程后,處于Runnable狀態,獲得CPU控制權后執行,接著處于Running狀態,如果沒有控制,正常執行完畢會自動消亡即Dead。處于Running狀態的線程,第一:調用sleep或者join方法或者阻塞IO會進入阻塞狀態,一旦釋放會自動進入Runnable狀態。第二:調用wait方法會使線程處于等待池(是個對象池),一旦調用notify()或者interupt()方法線程會進入鎖池(是個對象池),然后就會進入Runnable狀態,等待CPU控制權。第三:運行中的線程進入synchronized方法或者synchronized代碼段,會進入鎖池,并且只有在synchronized里面才能調用wait()方法。
當調用push方法的時候,當前線程鎖定this對象,當棧滿了,開始調用wait()方法,使生產者線程處于等待池。當消費者線程通知生產者線程繼續生產的時候,wait()方法終結,如果使用if條件,并且處于多線程狀態(有若干個生產者線程),那么這個時候有可能另外一個處于鎖池狀態的線程開始執行,那么該線程會生產導致棧滿,而這個時候剛執行完wait()方法的線程也開始生產,那么會導致溢出。所以采用while循環,繼續判斷棧是否滿,如果不滿,那么執行生產,這個時候絕對不會出現任何問題,因為synchronized該線程獲得鎖,其余線程無法進入,必定安全。釋放對象的鎖:1、執行完同步代碼塊,就會釋放鎖2、執行同步代碼塊的過程中,執行了鎖所屬對象的wait()方法,這個線程會釋放鎖,進入對象的等待池。3、執行同步代碼塊的過程中,遇到異常而導致線程終止,鎖也會釋放不會釋放鎖:1、執行了Thread.sleep()方法,當前線程放棄CPU,開始睡眠,但不會釋放鎖。2、執行同步代碼塊的過程中,執行了Thread.yield()方法,當前線程放棄CPU但不會釋放鎖。