天天看點

Oracle官方并發教程之線程對象

直接控制線程的建立和管理,每當應用程式需要執行一個異步任務的時候就為其建立一個線程

将線程的管理從應用程式中抽象出來作為執行器,應用程式将任務傳遞給執行器,有執行器負責執行。

應用程式在建立一個線程執行個體時,必須提供需要線上程中運作的代碼。有兩種方式去做到這一點:

需要注意的是,上述兩個例子都需要調用thread.start()方法來啟動一個新的線程。 哪一種方式是我們應該使用的?相對來說,第一種更加通用,因為runnable對象可以繼承于其他類(java隻支援單繼承,當一個類繼承與thread類後,就無法繼承與其他類)。第二種方法更易于在簡單的應用程式中使用,但它的局限就是:你的任務類必須是thread的子類。這個課程更加聚焦于第一種将runnable任務和thread類分離的方式。不僅僅是因為這種方式更加靈活,更因為它更适合後面将要介紹的進階線程管理api。 thread類定義了一些對線程管理十分有用的的方法。在這些方法中,有一些靜态方法可以給目前線程調用,它們可以提供一些有關線程的資訊,或者影響線程的狀态。而其他一些方法可以由其他線程進行調用,用于管理線程和thread對象。我們将在下面的章節中,深入探讨這些内容。

使用thread.sleep()方法可以暫停目前線程一段時間。這是一種使處理器時間可以被其他線程或者運用程式使用的有效方式。sleep()方法還可以用于調整線程執行節奏(見下面的例子)和等待其他有執行時間需求的線程(這個例子将在下一節示範)。

在thread中有兩個不同的sleep()方法,一個使用毫秒表示休眠的時間,而另一個是用納秒。由于作業系統的限制休眠時間并不能保證十分精确。休眠周期可以被interrups所終止,我們将在後面看到這樣的例子。不管在任何情況下,我們都不應該假定調用了sleep()方法就可以将一個線程暫停一個十分精确的時間周期。

main()方法聲明了它有可能抛出interruptedexception。當其他線程中斷目前線程時,sleep()方法就會抛出該異常。由于這個應用程式并沒有定義其他的線程,是以并不用關心如何處理該異常。

中斷是給線程的一個訓示,告訴它應該停止正在做的事并去做其他事情。一個線程究竟要怎麼響應中斷請求取決于程式員,不過讓其終止是很普遍的做法。這是本文重點強調的用法。

Oracle官方并發教程之線程對象

一個線程通過調用對被中斷線程的thread對象的interrupt()方法,發送中斷信号。為了讓中斷機制正常工作,被中斷的線程必須支援它自己的中斷(即要自己進行中斷)

線程如何支援自身的中斷?這取決于它目前正在做什麼。如果線程正在頻繁調用會抛interruptedexception異常的方法,在捕獲異常之後,它隻是從run()方法中傳回。例如,假設在sleepmessages的例子中,關鍵的消息循環線上程的runnable對象的run方法中,代碼可能會被修改成下面這樣以支援中斷:

許多會抛interruptedexception異常的方法(如sleep()),被設計成接收到中斷後取消它們目前的操作,并在立即傳回。

如果一個線程長時間運作而不調用會抛interruptedexception異常的方法會怎樣? 那它必須周期性地調用thread.interrupted()方法,該方法在接收到中斷請求後傳回true。例如:

在這個簡單的例子中,代碼隻是檢測中斷,并在收到中斷後退出線程。在更複雜的應用中,抛出一個interruptedexception異常可能更有意義。

這使得中斷處理代碼能集中在catch語句中。

中斷機制通過使用稱為中斷狀态的内部标記來實作。調用thread.interrupt()設定這個标記。當線程通過調用靜态方法thread.interrupted()檢測中斷時,中斷狀态會被清除。非靜态的isinterrupted()方法被線程用來檢測其他線程的中斷狀态,不改變中斷狀态标記。

按照慣例,任何通過抛出一個interruptedexception異常退出的方法,當抛該異常時會清除中斷狀态。不過,通過其他的線程調用interrupt()方法,中斷狀态總是有可能會立即被重新設定。

join()方法可以讓一個線程等待另一個線程執行完成。若t是一個正在執行的thread對象,

将會使目前線程暫停執行并等待t執行完成。重載的join()方法可以讓開發者自定義等待周期。然而,和sleep()方法一樣join()方法依賴于作業系統的時間處理機制,你不能假定join()方法将會精确的等待你所定義的時長。

如同sleep()方法,join()方法響應中斷并在中斷時抛出interruptedexception。

messageloop現場将會列印一系列的資訊。如果中斷在它列印完所有資訊前發生,它将會列印一個特定的消息并退出。