轉 Java中wait和sleep方法的區別 java中的sleep()和wait()的區別

 

一、二者的區別

  • 這兩個方法來自不一樣的類分別是Thread和Object  
  • 最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其餘線程可使用同步控制塊或者方法(鎖代碼塊和方法鎖)。  
  • wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep能夠在任何地方使用(使用範圍)  
  • sleep必須捕獲異常,而wait,notify和notifyAll不須要捕獲異常  
  • sleep方法屬於Thread類中方法,表示讓一個線程進入睡眠狀態,等待必定的時間以後,自動醒來進入到可運行狀態,不會立刻進入運行狀態,由於線程調度機制恢復線程的運行也須要時間,一個線程對象調用了sleep方法以後,並不會釋放他所持有的全部對象鎖,因此也就不會影響其餘進程對象的運行。但在sleep的過程當中過程當中有可能被其餘對象調用它的interrupt(),產生InterruptedException異常,若是你的程序不捕獲這個異常,線程就會異常終止,進入TERMINATED狀態,若是你的程序捕獲了這個異常,那麼程序就會繼續執行catch語句塊(可能還有finally語句塊)以及之後的代碼。  
  • 注意sleep()方法是一個靜態方法,也就是說他只對當前對象有效,經過t.sleep()讓t對象進入sleep,這樣的作法是錯誤的,它只會是使當前線程被sleep 而不是t線程  
  •  wait屬於Object的成員方法,一旦一個對象調用了wait方法,必需要採用notify()和notifyAll()方法喚醒該進程;若是線程擁有某個或某些對象的同步鎖,那麼在調用了wait()後,這個線程就會釋放它持有的全部同步資源,而不限於這個被調用了wait()方法的對象。wait()方法也一樣會在wait的過程當中有可能被其餘對象調用interrupt()方法而產生  

 

若是線程A但願當即結束線程B,則能夠對線程B對應的Thread實例調用interrupt方法。若是此刻線程B正在wait/sleep/join,則線程B會馬上拋出InterruptedException,在catch() {} 中直接return便可安全地結束線程。html

須要注意的是,InterruptedException是線程本身從內部拋出的,並非interrupt()方法拋出的。對某一線程調用interrupt()時,若是該線程正在執行普通的代碼,那麼該線程根本就不會拋出InterruptedException。可是,一旦該線程進入到wait()/sleep()/join()後,就會馬上拋出InterruptedException。java

 

waite()和notify()由於會對對象的「鎖標誌」進行操做,因此它們必須在synchronized函數或synchronized block中進行調用。若是在non-synchronized函數或non-synchronizedblock中進行調用,雖然能編譯經過,但在運行時會發生illegalMonitorStateException的異常。安全

 

補充兩個重要的方法:yield()和join()函數

yield方法  post

暫停當前正在執行的線程對象。  url

yield()方法是中止當前線程,讓同等優先權的線程或更高優先級的線程有執行的機會。若是沒有的話,那麼yield()方法將不會起做用,而且由可執行狀態後立刻又被執行。   spa

join方法是用於在某一個線程的執行過程當中調用另外一個線程執行,等到被調用的線程執行結束後,再繼續執行當前線程。如:t.join();//主要用於等待t線程運行結束,若無此句,main則會執行完畢,致使結果不可預測。  .net

 

說一下爲何使用wait()方法時,通常是須要while循環而不是if?

while(!執行條件) { wait(); } .... if(!執行條件) { wait(); } ....

while會一直執行循環,直到條件知足,執行條件纔會繼續往下執行。if只會執行一次判斷條件,不知足就會等待。這樣就會出現問題。線程

咱們知道用notify() 和notifyAll()能夠喚醒線程,通常咱們經常使用的是notifyAll(),由於notify(),只會隨機喚醒一個睡眠線程,並不必定是咱們想要喚醒的線程。若是使用的是notifyAll(),喚醒全部的線程,那你怎麼知道他想喚醒的是某個正在等待的wait()線程呢,若是用while()方法,就會再次判斷條件是否是成立,知足執行條件了,就會接着執行,而if會直接喚醒wait()方法,繼續往下執行,根本無論這個notifyAll()是否是想喚醒的是本身仍是別人,可能此時if的條件根本沒成立。code

舉個例子:

while去水果店買蘋果,沒有了,而後while就和水果店老闆說,有水果的時候通知我,我先回去了。if也去水果店買蘋果,沒有了,而後if就和水果店老闆說,有水果的時候通知我,我先回去了。過一段時間,水果店老闆發短信告訴while和if,有水果了,while去一看,水果店只是進了香蕉,並非蘋果,因此不是想要的水果,因而回去繼續等水果店老闆通知,而if根本就不看是否是本身想要的蘋果,直接就叫老闆送10斤水果過來,這樣會致使你獲得錯誤的結果。

 

參考文獻:

Java中wait 和sleep 方法比較

JAVA—sleep()和wait()的區別

java中的sleep()和wait()的區別

相關文章
相關標籤/搜索