sleep方法和wait方法的區別?


sleep 是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep 不會釋放對象鎖。
wait 是Object 類的方法,對此對象調用wait 方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify 方法(或notifyAll)后本線程才進入對象鎖定池准備獲得對象鎖進入運行狀態。

 

1、這兩個方法來自不同的類分別是Thread和Object
2、最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
3、wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用(使用范圍)

  1. synchronized(x){
  2.   x.notify()
  3.   //或者wait()
  4.   }

4、sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常。

 

sleep方法屬於Thread類中方法,表示讓一個線程進入睡眠狀態,等待一定的時間之后,自動醒來進入到可運行狀態,不會馬上進入運行狀態,因為線程調度機制恢復線程的運行也需要時間,一個線程對象調用了sleep方法之后,並不會釋放他所持有的所有對象鎖,所以也就不會影響其他進程對象的運行。但在sleep的過程中過程中有可能被其他對象調用它的interrupt(),產生InterruptedException異常,如果你的程序不捕獲這個異常,線程就會異常終止,進入TERMINATED狀態,如果你的程序捕獲了這個異常,那么程序就會繼續執行catch語句塊(可能還有finally語句塊)以及以后的代碼。

注意sleep()方法是一個靜態方法,也就是說他只對當前對象有效,例如t是一個線程,通過指定t.sleep()讓t對象進入sleep,這樣的做法是錯誤的,它只會是使當前線程被sleep 而不是t線程。

wait屬於Object的成員方法,一旦一個對象調用了wait方法,必須要采用notify()和notifyAll()方法喚醒該進程;如果線程擁有某個或某些對象的同步鎖,那么在調用了wait()后,這個線程就會釋放它持有的所有同步資源,而不限於這個被調用了wait()方法的對象。

 

2)Wait()和notify():如果條件不滿足,則等待。當條件滿足時,等待該條件的線程將被喚醒。一般用在synchronized機制中。

例如:線程A

   synchronized(obj) {

               while(!condition) {

                         obj.wait();

                 }

                obj.doSomething();

.....

  }

當線程A獲得了obj鎖后,發現條件condition不滿足,無法繼續下一處理,於是線程A就wait()。在另一線程B中,如果B更改了某些條件,使得線程A的condition條件滿足了,就可以喚醒線程A。

線程B

      synchronized(obj) {

              condition = true;

              obj.notify();

        }

需要注意的概念是:  

   1.調用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) {……} 代碼段內(或synchronized方法中)。  

   2.調用obj.wait()后,線程A就釋放了obj的鎖,否則線程B無法獲得obj鎖,也就無法在synchronized(obj) {……} 代碼段內喚醒A.  

   3.當obj.wait()方法返回后,線程A需要再次獲得obj鎖,才能繼續執行。  

   4.如果A1,A2,A3都obj.wait(),則B調用obj.notify()只能喚醒A1,A2,A3中的一個(具體哪一個由JVM決定)。  

   5.obj.notifyAll()則能全部喚醒A1,A2,A3,但是要繼續執行obj.wait()的下一條語句,必須獲得obj鎖,因此,A1,A2,A3只有一個有機會獲得鎖繼續執行,例如A1,其余的需要等待A1釋放obj鎖之后才能繼續執行。

   6.當B調用obj.notify/notifyAll的時候,B正持有obj鎖,因此,A1,A2,A3雖被喚醒,但是仍無法獲得obj鎖。直到B退出synchronized塊,釋放obj鎖后,A1,A2,A3中的一個才有機會獲得鎖繼續執行。

 

3)為什么wait(),notify()方法要和synchronized一起使用?

因為wait()方法是通知當前線程等待並釋放對象鎖,notify()方法是通知等待此對象鎖的線程重新獲得對象鎖,然而,如果沒有獲得對象鎖,wait方法和notify方法都是沒有意義的,即必須先獲得對象鎖,才能對對象鎖進行操作,於是,才必須把notify和wait方法寫到synchronized方法或是synchronized代碼塊中了。

 
 參考:
http://blog.csdn.net/nyistzp/article/details/12878417


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM