1. 程式人生 > 其它 >通俗易懂的告訴你java多執行緒中wait和sleep的區別

通俗易懂的告訴你java多執行緒中wait和sleep的區別

在學習java多執行緒的過程中,我們能一定見過sleep和wait這兩個方法,這兩個方法都是多執行緒中經常使用的方法,並且它們都可以讓當前執行緒停下來。可是你知道嗎?這兩個方法其實有很大的差別。

01多執行緒的狀態

要想弄懂這兩個方法的差別,我們可以先簡單地看一下多執行緒的執行狀態

1. New:初始狀態,執行緒被建立,沒有呼叫start()

2. Runnable:執行狀態,Java執行緒把作業系統中的就緒和執行兩種狀態統一稱為“執行中”

3. Blocked:阻塞,執行緒進入等待狀態,執行緒因為某種原因,放棄了CPU的使用權

4. Waiting:等待狀態

5. timed_waiting:超時等待狀態,超時以後自動返回

6. terminated:終止狀態,當前執行緒執行完畢

這裡介紹多執行緒的幾個狀態,主要是想大家看下,在這幾個狀態的轉化中wait和sleep的作用。

通過上面的圖可以看到

wait使執行緒從Running到Waitingsleep使執行緒從Running到timed_waiting:超時等待狀態,時間一到自動變回Running狀態可以看出wait和sleep都可以使執行緒中止,但是也存在許多不同,下面就逐一來看下wait和sleep的不同之處

02區別

一、sleep是Thread的方法,wait是Object的方法

sleep的原始碼

可以看到sleep在Thread類中,並且是Thread的一個靜態本地方法,所以平時我們呼叫sleep的時候就Thread.sleep()這樣就可以進行呼叫了。

wait原始碼

可以看到wait方法在Object類中,因為java中所有的類都是繼承自object的,所以所有類都可以呼叫wait方法,這是一個final的方法,同時不是一個靜態方法,所以呼叫該方法需要先例項化一個Object物件才可以

二、sleep不會去釋放鎖,但是wait會釋放這個鎖,並把這個wait的執行緒加入到這個鎖的等待佇列中去

廢話少說看例子!

sleep不會釋放鎖

通過輸出結果我們可以看到,t1和t2這兩個執行緒是順序輸出的,因為sleep不會釋放鎖,必須等sleep結束了才會釋放鎖,下一個執行緒才能去執行。

wait會釋放鎖

通過這個輸出結果可以看到t1和t2這兩個執行緒幾乎是同時執行的,這是因為wait在中止執行緒的時候是直接把執行緒放到等待佇列中的,會直接釋放鎖

三、使用wait必須要定義一個synchronized,而sleep不需要

廢話少說,看例子!

看輸出結果可以發現,會報一個非法的監視器錯誤,這就是因為wait必須要在synchronized修飾的語句塊或者方法和類中

四、使用sleep不需要被喚醒,但是wait是需要notify()或者notifyAll()去喚醒的,除了wait(1000)這種形式

03總結

多執行緒的狀態變化還是比較複雜的,在這其中wait和sleep都能起到使執行緒中止的目的,但是它倆有很多區別,在實際的使用中要根據具體情況來定。同時“wait和sleep的區別”是很多面試官都喜歡問的,希望看完這篇文章對大家有幫助。