1. 程式人生 > 其它 >Java程式設計師如何通過跳槽薪資翻倍?Java執行緒狀態以及 sheep(

Java程式設計師如何通過跳槽薪資翻倍?Java執行緒狀態以及 sheep(

Java程式設計師如何通過跳槽薪資翻倍?Java執行緒狀態以及 sheep(

5. 死亡(Dead):執行緒執行完了或因異常退出了run()方法,則該執行緒結束生命週期。

wait(), notify(), notifyAll()等方法介紹


這三個方法都是定義到Object類中,wait的作用是噹噹前執行緒釋放它所持有的鎖進入等待狀態,而notify和notifyAll則是喚醒當前物件上的等待執行緒。

notify() —— 喚醒在此物件監視器上等待的單個執行緒。

notifyAll() —— 喚醒在此物件監視器上等待的所有執行緒。

wait() —— 讓當前執行緒處於“等待(阻塞)狀態”,“直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法”,當前執行緒被喚醒(進入“就緒狀態”)。

wait(long timeout) —— 讓當前執行緒處於“等待(阻塞)狀態”,“直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量”,當前執行緒被喚醒(進入“就緒狀態”)。

wait(long timeout, int nanos) —— 讓當前執行緒處於“等待(阻塞)狀態”,“直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者其他某個執行緒中斷當前執行緒,或者已超過某個實際時間量”,當前執行緒被喚醒(進入“就緒狀態”)。

wait()會使“當前執行緒”等待,並且會釋放到它所佔用的“鎖標誌”,從而使執行緒所在物件中的其他synchronized資料可以被其他執行緒使用。

waite()和notify()因為會對物件的“鎖標誌”進行操作,所以它們必須在synchronized函式或synchronizedblock中進行呼叫。如果在non-synchronized函式或non-synchronizedblock中進行呼叫,雖然能編譯通過,但在執行時會發生IllegalMonitorStateException的異常。

負責喚醒等待執行緒的那個執行緒(我們稱為“喚醒執行緒”),它只有在獲取“該物件的同步鎖”(這裡的同步鎖必須和等待執行緒的同步鎖是同一個),並且呼叫notify()或notifyAll()方法之後,才能喚醒等待執行緒。雖然,等待執行緒被喚醒;但是,它不能立刻執行,因為喚醒執行緒還持有“該物件的同步鎖”。必須等到喚醒執行緒釋放了“物件的同步鎖”之後,等待執行緒才能獲取到“物件的同步鎖”進而繼續執行。

suspend()和?resume()方法


兩個方法配套使用,suspend()使得執行緒進入阻塞狀態,並且不會自動恢復,必須其對應的resume()被呼叫,才能使得執行緒重新進入可執行狀態。典型地,****suspend()和?resume()?被用在等待另一個執行緒產生的結果的情形:測試發現結果還沒有產生後,讓執行緒阻塞,另一個執行緒產生了結果後,呼叫?resume()使其恢復。

注意區別:

初看起來wait()?和?notify()?方法與suspend()和?resume()?方法對沒有什麼分別,但是事實上它們是截然不同的。區別的核心在於,前面敘述的suspend()及其它所有方法線上程阻塞時都不會釋放佔用的鎖(如果佔用了的話),而wait()?和?notify()?這一對方法則相反。

sleep() 和 yield()方法


這兩個方法都定義在Thread.java中

sleep()的作用是讓當前執行緒休眠(正在執行的執行緒主動讓出cpu,然後cpu就可以去執行其他任務),即當前執行緒會從“執行狀態”進入到“休眠(阻塞)狀態”。sleep()會指定休眠時間,執行緒休眠的時候會大於或者等於該休眠時間,當時間過後該執行緒重新被會形式,他會由“阻塞狀態”程式設計“就緒狀態”,從而等待cpu的排程執行,注意:sleep方法只是讓出了cpu的執行權,並不會釋放同步資源鎖。

yield()的作用是讓步,它能夠讓當前執行緒從“執行狀態”進入到“就緒狀態”,從而讓其他等待執行緒獲取執行權,但是不能保證在當前執行緒呼叫yield()之後,其他執行緒就一定能獲得執行權,也有可能是當前執行緒又回到“執行狀態”繼續執行,注意:這裡我將上面的“具有相同優先順序”的執行緒直接改為了執行緒,很多資料都寫的是讓具有相同優先順序的執行緒開始競爭,但其實不是這樣的,優先順序低的執行緒在拿到cpu執行權後也是可以執行,只不過優先順序高的執行緒拿到cpu執行權的概率比較大而已,並不是一定能拿到。

舉個例子:一幫朋友在排隊上公交車,輪到Yield的時候,他突然說:我不想先上去了,咱們大家來競賽上公交車。然後所有人就一塊衝向公交車,

有可能是其他人先上車了,也有可能是Yield先上車了。

但是執行緒是有優先順序的,優先順序越高的人,就一定能第一個上車嗎?這是不一定的,優先順序高的人僅僅只是第一個上車的概率大了一點而已,

最終第一個上車的,也有可能是優先順序最低的人。並且所謂的優先順序執行,是在大量執行次數中才能體現出來的。

wait和sleep的區別


相同點:

1. 他們都是在多執行緒的環境下,都可以在程式的調用出阻塞指定的毫秒數並且返回

2. 兩個方法都可以通過interrupt()方法打斷執行緒的暫停狀態,但是執行緒會丟擲InterruptedException。需要注意的是,InterruptedException是執行緒自己從內部丟擲的,並不是interrupt()方法丟擲的。對某一執行緒呼叫 interrupt()時,如果該執行緒正在執行普通的程式碼,那麼該執行緒根本就不會丟擲InterruptedException。但是,一旦該執行緒進入到 wait()/sleep()/join()後,就會立刻丟擲InterruptedException 。?

不同點:

1. Thread類的方法:sleep(),yield()

? ? ?Object的方法:wait()和notify()、notifyAll()

2. 每個物件都有一個鎖來控制同步訪問。Synchronized關鍵字可以和物件的鎖互動,來實現執行緒的同步。?sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他執行緒可以使用同步控制塊或者方法。?

3. wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用 。注意:wiat()必須放在synchronized block中,否則會在program runtime時扔出“java.lang.IllegalMonitorStateException”異常。

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

最後

筆者已經把面試題和答案整理成了面試專題文件,有想獲取到借鑑參考的朋友:點贊關注後,戳這裡即可免費領取

?

?

?