關於Java中進程和線程的詳解

來源:互聯網
上載者:User

標籤:進程和線程   strong   cpu   call   ges   轉換   建立線程   放棄   進程式控制制   

一.進程:是程式的一次動態執行,它對應著從代碼載入,執行至執行完畢的一個完整的過程,是一個動態實體,它有自己的生命

          周期。它因建立而產生,因調度而運行,因等待資源或事件而被處於等待狀態,因完成任務而被撤消。反映了一個程式在

         一定的資料 集上啟動並執行全部動態過程。通過進程式控制制塊(PCB)唯一的標識某個進程。同時進程佔據著相應的資源(例如包

         括cpu的使用 ,輪轉時間以及一些其它裝置的許可權)。是系統進行資源分派和調度的一個獨立單位。

           程式和進程之間的主要區別在於:

                       狀態         是否具有資源       是否有唯一標識      是否具有並發性

            進程     動態                有                      有                     有

            程式     靜態                無                      無                     無     

         進程的基本狀態:

       1、就緒(Ready)狀態

       當進程已指派到除CPU以外的所有必要資源後,只要在獲得CPU,便可立即執行,進程這時的狀態就稱為就緒狀態。在一個系統中處於就緒狀態的進程可能有多個,通常將他們排成一個隊列,稱為就緒隊列。

       2、執行狀態

       進程已獲得CPU,其程式正在執行。在單處理機系統中,只有一個進程處於執行狀態;再多處理機系統中,則有多個進程處於執行狀態。

       3、阻塞狀態

       正在執行的進程由於發生某事件而暫時無法繼續執行時,便放棄處理機而處於暫停狀態,亦即程式的執行受到阻塞,把這種暫停狀態稱為阻塞狀態,有時也稱為等待狀態或封鎖狀態。

三種進程之間的轉換圖:

   線程: 可以理解為進程的多條執行線索,每條線索又對應著各自獨立的生命週期。線程是進程的一個實體,是CPU調度和指派的

            基本單位,它是比進程更小的能獨立啟動並執行基本單位。一個線程可以建立和撤銷另一個線程,同一個進程中的多個線程之

            間可以並發執行。

            這裡在詳細講解一下Java中的進程和線程的概念。

            Java中的線程要經曆4個過程

            1)建立

                  建立一個Java線程常見的有兩種方式:

                  繼承Thread類和實現Runnable介面這兩種方式。

            2)執行

                      線程建立後僅僅佔有了記憶體資源,在JVM管理的線程中還沒有該線程,該線程必須調用start方法通知JVM,這樣JVM

                 就會知道又有一個新的線程排隊等候了。如果當前線程輪到了CPU的使用許可權的話,當前線程就會繼續執行。

           3)中斷

                a.JVM將CPU的使用許可權從當前線程切換到其它線程,使本線程讓出CPU的使用許可權而處於中斷狀態。

                b.線程在執行過程中調用了sleep方法,使當前線程處於休眠狀態。

                c.線程在執行的過程中調用wait方法

                d.線程在使用cpu資源期間,執行了某個操作而進如阻塞狀態。

           4)死亡

               死亡的線程不在具有執行能力。線程死亡的原因有二:

                a.線程正常運行結束而引起的死亡,即run方法執行完畢。

                b.線程被提前強制終止。

 

二:線程的建立及使用

java使用Thread類代表線程,所有的線程對象都必須是Thread或者其子類的執行個體,每個線程的作用是完成一定任務,實際上是就是執行一段程式流(一段順序執行的代碼)

方案一:繼承Thread類建立線程類

步驟:1.定義Thread類的子類 並重寫該類的Run方法,該run方法的方法體就代表了該線程需要完成的任務

      2.建立Thread類的執行個體,即建立了線程對象

      3.調用線程的start方法來啟動線程

 

結論:使用繼承子Thread類的子類來建立線程類時,多個線程無法共用線程類的執行個體變數(比如上面的i)

方案二:實現Runnable介面

1:定義Runnable介面的實作類別,並重寫它的Run方法,run方法同樣是該線程的執行體!

2:建立Runnable實作類別的執行個體,並將此執行個體作為Thread的target建立一個Thread對象,該Thread對象才是真正的線程對象!

3:調用start方法啟動該線程

結論:採用Ruunable介面的方式建立多個線程可以共用線程類的執行個體變數,這是因為在這種方式下,程式建立的Runnable對象只是線程的target,而多個線程可以共用一個target,所以多個線程可以共用一個執行個體變數

 

通過Runnable實現多線程其實就是將run封裝成線程的執行體,但是目前java無法將任意方法封裝成線程執行體

方案三:使用callable和future建立線程

 

從Java5開始,Java提供 Callable介面,Callable介面提供了一個call()方法可以作為線程執行體,看起來和Runnable很像,但call()方法更強大——call()方法可以有傳回值、call()方法可以拋出異常

 

Java5提供了Future介面來代表Callable介面的call()方法的傳回值,並為Future介面提供了一個FutureTask實作類別,該實作類別實作類別Future介面,也實現了Runnable介面——可以作為Thread的target。

實現步驟:

1:建立Callable介面的實作類別,並實現call方法,該call方法會成為線程執行體,且call方法具有傳回值,在建立callable介面的實作類別!

2:使用FutrueTask類來封裝Callable對象,該FutrueTask封裝類Callable的call方法的傳回值

3:使用FutrueTask對象作為Thread的target建立並啟動新線程!

4:使用FutrueTask的get方法擷取執行結束後的傳回值

 

結論:採取Runnable、Callable的優勢在於——線程類只是實現了Runnable或Callable介面,還可以繼承其它類;在這種方法下,多個線程可以共用一個target對象,因此非常適合多個相同線程處理同一份資源的情況,從而將CPU、代碼和資料分開,形參清晰的模型,體現了面對對象的編程思想。劣勢在於編程複雜度略高。

 

關於Java中進程和線程的詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.