Java多線程詳述

來源:互聯網
上載者:User

標籤:包含   沒有   私人   資料   rup   計數   思想   多線程   狀態   

線程概述作業系統支援同時運行多個任務,每個任務都是一個程式,每個運行中的程式就是一個進程。當一個程式運行時,內部可能包含多個順序執行流,每個順序執行流就是一個線程。 1.線程和進程進程是系統進行資源分派和調度的一個獨立單位,一般而言,進程包括如下三個特徵:1、獨立性:進程是系統中獨立存在的實體,它可以擁有自己獨立的資源,每一個進程都擁有自己的私人的地址空間。在沒有經過進程本身允許的情況下,一個使用者進程不可以直接存取其它進程的地址空間。2、動態性:進程和程式的區別在於,程式只是一個靜態指令集合,而進程是一個正在系統中活動的指令集合。在進程中加入了時間的概念。進程具有自己的生命週期和各種不同的狀態,這些概念在程式中都是不具備的。3、並發性:多個進程可以在單個處理器上並發執行,多個進程之間不會相互影響。 並發性和並行性區別:並行指在同一時刻,有多條指令在多個處理器上同時執行;並髮指在同一時刻只能有一條指令執行,但多個進程指令被快速輪換執行,使得宏觀上具有多個進程同時執行的效果。 線程是進程的執行單元,是進程的組成部分,一個進程可以擁有多個線程。線程可以擁有自己的堆棧、自己的程式計數器和自己的局部變數,但不擁有系統資源。它可以與其它線程共用父進程的資源。線程是獨立啟動並執行,它並不知道進程中是否還有其他線程存在。線程的執行是搶佔式的,也就是說,當前啟動並執行線程在任何時候都可能被掛起,以便另外一個線程可以運行。一個線程可以建立和撤銷另一個線程,同一個進程中的多個線程之間可以並發執行。 使用多線程的優點:1、進程之間不能共用記憶體,但線程之間共用記憶體很容易。2、系統建立進程時需要為該進程重新分配系統資源,但建立線程代價則小得多。因此使用多線程來實現實現多任務並發比多進程效率更高。3、Java語言內建了多線程功能支援,而不是單純地作為底層作業系統的調度方式,從而簡化了Java的多線程編程。 2.線程的建立和啟動Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的執行個體。每個線程的作用是完成一定的任務,實際上是執行一段程式流(一段順序執行的代碼)。Java使用線程執行體來代表這段程式流。 一、繼承Thread類建立線程類(1)、定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法執行體就代表了線程需要完成的任務。因此run()方法就稱為線程執行體。(2)、建立Thread子類的執行個體,即建立線程對象。(3)、調用線程對象的start()方法來啟動該線程。注意:使用繼承Thread類的方法來建立線程類的時候,多個線程之間無法共用線程類的執行個體變數。 二、實現Runnable介面建立線程類(1)、定義Runnable介面的實作類別,並重寫該介面的run()方法,該run()方法的方法體同樣是該線程的線程執行體。(2)、建立Runnable實作類別的執行個體,並以此執行個體作為Thread的target來建立Thread對象,該Thread對象才是真正的線程對象。注意:Runnable對象僅僅作為Thread對象的target,Runnable實作類別裡包含的run()方法僅作為線程執行體。而實際的線程對象依然是Thread執行個體,只是該Thread線程負責執行其target的run()方法。(3)、調用線程對象的start()方法來啟動該線程。 對比兩種方式:通過繼承Thread類來獲得當前線程對象比較簡單,直接使用this就行了,但是通過實現Runnable介面來獲得當前線程對象則必須使用Thread.currentThread()方法。 三、使用Callable和Future建立線程Callable介面提供了一個call()方法可以作為線程執行體,但call()方法比run()方法功能更加強大。1、call()方法可以有傳回值。2、call()方法可以聲明拋出異常。Java5提供了Future介面來代表Callable介面裡call()方法的傳回值,並為Future介面提供了一個FutureTask實作類別,該實作類別實現了Future介面,並實現了Runnable介面----可以作為Thread類的target。在Future介面裡定義了如下幾個公用方法來控制它關聯的Callable任務。(1)、boolean cancel(boolean mayInterruptIfRunning):試圖取消該Future裡關聯的Callable任務。(2)、V  get():返回Callable任務裡call()方法的傳回值。調用該方法將導致程式阻塞,必須等到子線程結束後才會得到傳回值。(3)、V  get(long timeout,TimeUnit unit):返回Callable任務裡call()方法的傳回值。該方法讓程式最多阻塞timeout和unit指定的時間,如果經過指定時間後Callable任務依然沒有傳回值,將會拋出TimeoutException異常。(4)、boolean isCancelled():如果在Callable任務正常完成前被取消,則返回true。(5)、boolean isDone():如果Callable任務已完成,則返回true。注意:Callable介面有泛型限制,Callable介面裡的泛型形參類型與call()方法傳回值類型相同。建立並啟動有傳回值的線程步驟如下:1、建立Callable介面的實作類別,並實現call()方法,該call()方法將作為線程執行體,且該call()方法沒有傳回值,再建立Callable實作類別的執行個體。2、使用FutureTask類來封裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的傳回值。3、使用FutureTask對象作為Thread對象的target建立並啟動新線程。4、調用FutureTask對象的get()方法來獲得子線程執行結束後的傳回值。 採用實現Runnable、Callable介面的方式建立多線程的優缺點:1、線程類只是實現了Runnable介面或者Callable介面,還可以繼承其他類。2、在這種方式下,多個線程可以共用同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和資料分開,形成清晰的模型,較好地體現物件導向的思想。缺點是:編程稍稍複雜,如果需要訪問當前線程,則必須使用Thread.currentThread()方法。 採用繼承Thread類的方式建立多線程的優缺點:1、缺點是,因為線程類已經繼承了Thread類,所以不能再繼承其他父類。2、優點是,編寫簡單,如果要訪問當前線程,則無須使用Thread.currentThread()方法,直接使用this即可獲得當前線程。 總結:採用Runnable介面、Callable介面的方式來建立多線程。

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.