【Java基礎】:執行緒控制

連江偉發表於2016-08-31

        Java提供了一些控制執行緒執行順序的非常方便的工具方法,通過這些便捷的工具方法可以讓我們更加靈活地控制執行緒的執行。

        今天我們主要討論控制執行緒的幾個常用方法:join、sleep、yield以及如何調整執行緒的優先順序。

        Join執行緒

        Thread提供了讓一個執行緒等待另一個執行緒完成之後自己再接著執行的方法:join方法。當某個程式執行流中呼叫其他執行緒的join方法時,呼叫執行緒將被阻塞,直到被join方法加入的join執行緒執行完成為止。

        執行緒sleep

        如果我們需要讓當前正在執行的執行緒暫停一段時間,並進入阻塞狀態,則可以通過呼叫Thread類的靜態方法sleep方法。

       

 

        執行緒yield

        yield方法是一個和sleep方法有點類似的方法,它也是一個Thread類提供的靜態方法,它也可以讓當前正在執行的執行緒暫停,但是它不會阻塞該執行緒,它只是將該執行緒轉入就緒狀態。yield只是讓當前執行緒暫停一下,讓系統的執行緒排程器重新排程一次,完全可能的情況是:當某個執行緒呼叫了yield方法暫停之後,執行緒排程器又再一次排程出來它重新執行。

        實際上,當某個執行緒呼叫了yield方法暫停之後,只有優先順序與當前執行緒相同,或者優先順序比當前執行緒更高的就緒狀態的執行緒才有可能獲得執行的機會。

        那麼sleep方法和yield方法的區別是什麼呢?

        1sleep方法暫停當前執行緒後,會給其他執行緒執行的機會,不會關心其他執行緒的優先順序是否比當前執行緒高還是低。而yield方法則只會給優先順序相同或者優先順序更高的執行緒執行機會。

      2sleep方法會將執行緒轉入阻塞狀態,直到經過阻塞時間才會轉入就緒狀態,而yield方法不經過阻塞狀態,直接強制進入就緒狀態。因此完全有可能某個執行緒呼叫了yield方法之後,立即再次獲得處理器資源接著執行。

        3sleep方法宣告丟擲InterruptedException異常,所以呼叫sleep方法時要麼捕捉該異常,要麼顯式宣告丟擲該異常。而yield方法則沒有必要宣告丟擲任何異常。

        4sleep方法比yield方法有更好的移植性,通常不建議使用yield方法來控制併發執行緒的執行。

        改變執行緒優先順序

        在上文介紹yield方法時,提到了執行緒的優先順序。那麼執行緒的優先順序如何設定呢?

        每個執行緒預設的優先順序都與建立它的父執行緒具有相同的優先順序,在預設情況下,main執行緒具有普通優先順序,由main執行緒建立的子執行緒也有普通優先順序。

        Thread提供了setPriority(intnewPriority)和getPriority()方法來設定和返回指定執行緒的優先順序,其中setPriority方法的引數可以是一個整數,範圍為1-10之間,也可以使用Thread類的三個靜態常量:分別是MAX_PRIORITY=10,MIN_PRIORITY=1和NORM_PRIORITY=5。

        後臺程式

        最後再來說一說這個後臺程式,顧名思義就是在後臺執行的執行緒,他的任務是為其他的執行緒提供服務,這種執行緒被稱為Daemon Thread,又被稱為守護執行緒或者是精靈執行緒。JVM的垃圾回收執行緒就是典型的後臺執行緒。後臺執行緒有個特徵:如果所有的前臺執行緒都死亡了,後臺執行緒會自動死亡。

        呼叫Thread物件的setDaemon(true)方法可以將指定執行緒設定成後臺執行緒,但是需要注意的是setDaemon方法必須在start方法之前被呼叫,才可以成功設定為後臺執行緒。還有一個用於判斷指定執行緒是否為後臺程式的方法——isDaemon()。當整個虛擬機器中只剩下後臺程式時,程式就沒有繼續執行的必要了,所以虛擬機器也就退出了。

相關文章