如果你沒有接觸過java的多線程,那么多對於這兩個方法可能有點陌生,看名字好像這兩個方法是差不多的,但是實際上面差別好大。
首先我們看一下官方的API
Sleep(sleep有兩個方法,另一個方法傳遞兩個參數,還有一個參數也是時間,只不過是納秒級別的,所以和這個方法幾乎一樣,所以這里只分析這個毫秒級別的方法)
public static void sleep(long millis) throws InterruptedException
首先是個靜態的方法,入參是一個毫秒數,會拋出InterruptedException異常
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
讓當前執行的線程睡眠(臨時停止執行)一段毫秒數的時間,這個時間的精確性受到系統計時器和程序調度精度影響。這個線程不會失去任何監視器的所有權。
wait(也有多個方法,就不一一介紹了)
public final void wait()throws InterruptedException
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
讓當前進程等待直到另一個其他的線程代理調用了notify() 方法或者notifyAll() 方法之后。換句話說,這個方法的行為和wait(0)方法是類似的。
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
當前線程一定要有自己對象的監視器。這個線程釋放了自己的監視器然后等待直到其他線程換線這個等待線程的監視器,通過notify() 方法或者notifyAll() 方法。然后該線程將等到重新獲得對監視器的所有權后才能繼續執行。
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }
后面對這兩個方法做個總結
共同點 :
1. 他們都是在多線程的環境下,都可以在程序的調用處阻塞指定的毫秒數,並返回。
2. wait()和sleep()都可以通過interrupt()方法 打斷線程的暫停狀態 ,從而使線程立刻拋出InterruptedException。
如果線程A希望立即結束線程B,則可以對線程B對應的Thread實例調用interrupt方法。如果此刻線程B正在wait/sleep/join,則線程B會立刻拋出InterruptedException,在catch() {} 中直接return即可安全地結束線程。
需要注意的是,InterruptedException是線程自己從內部拋出的,並不是interrupt()方法拋出的。對某一線程調用 interrupt()時,如果該線程正在執行普通的代碼,那么該線程根本就不會拋出InterruptedException。但是,一旦該線程進入到 wait()/sleep()/join()后,就會立刻拋出InterruptedException 。
不同點 :
1.每個對象都有一個鎖來控制同步訪問。Synchronized關鍵字可以和對象的鎖交互,來實現線程的同步。
sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
2.wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用
3.sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常
4.sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep不會釋放對象鎖。
5.wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池准備獲得對象鎖進入運行狀態。