對比分析Java中的各個線程相關的wait()、notify()、sleep()、interrupt()方法
sleep()和wait()方法都是暫停當前正在執行的線程,出讓CPU資源。
public static void sleep(long millis) throws InterruptedException
public static void sleep(long millis, int nanos) throws InterruptedException
public final void wait() throws InterruptedException
public final void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
調用對象的wait()、notify()、notifyAll()方法的線程,必須是作為此對象監視器的所有者。常見的場景便是就是synchronized關鍵字的語句塊內部使用這3個方法,如果直接在線程中使用wait()、notify()、notifyAll()方法,那麼會拋出異常IllegalMonitorStateException,拋出的異常表明某一線程已經試圖等待對象的監視器,或者試圖通知其他正在等待對象的監視器而本身沒有指定監視器的線程。。
調用wait()方法的線程,在調用該線程的interrupt()方法,則會重新嘗試獲取對象鎖。只有當獲取到對象鎖,才開始拋出相應的異常,則執行該線程之後的程序。
interrupt()方法的工作僅僅是改變中斷狀態,並不是直接中斷正在運行的線程。中斷的真正原理是當線程被Object.wait(),Thread.join()或sleep()方法阻塞時,調用interrupt()方法後改變中斷狀態,而wait/join/sleep這些方法內部會不斷地檢查線程的中斷狀態值,當發現中斷狀態值改變時則拋出InterruptedException異常;對於沒有阻塞的線程,調用interrupt()方法是沒有任何作用。
yield()方法使當前線程出讓CPU執行時間,當並不會釋放當前線程所持有的鎖。執行完yield()方法後,線程從Running狀態轉變為Runnable狀態,既然是Runnable狀態,那麼也很可能馬上會被CPU調度再次進入Running狀態。