java使用thread類代表線程,所有的線程對象都必須是thread類或者其子類的執行個體。每個下次你哼的作用是完成一定的任務,實際上就是執行一段程式流(一段順序執行的代碼)。java使用線程執行體來代表這段程式流
在java線程的建立有三種方式
步驟如下
定義<code>thread</code>類的子類,并重寫該類的<code>run()</code>方法,該<code>run()</code>方法的方法體就代表了線程需要完成的任務。是以把<code>run()</code>方法稱為線程執行體。
建立<code>thread</code>子類的執行個體,即建立了線程的對象。
調用線程對象的<code>start()</code>方法來啟動線程。
步驟如下:
定義<code>runnable</code>接口的實作類,并重寫該接口的<code>run()</code>方法,該<code>run()</code>方法體同樣是該線程的線程執行體。
建立<code>runnable</code>實作類的執行個體,并以此執行個體作為<code>thread</code>的<code>target</code>來建立<code>thread</code>對象,該<code>thread</code>對象才是真正的線程對象。
調用線程對象的<code>start()</code>方法來啟動該線程。
建立<code>callable</code>實作類的執行個體。并實作<code>call()</code>方法,該<code>call()</code>方法将作為線程執行體,且該<code>call()</code>方法有傳回值,在建立<code>callable</code>實作類的執行個體。從java8開始,可以直接使用lambda表達式建立<code>callable</code>對象。
使用<code>futuretask</code>類來包裝<code>callable</code>對象,該<code>futuretask</code>對象封裝了該<code>call</code>對象的<code>call()</code>方法的傳回值。
使用<code>futuretask</code>對象作為<code>thread</code>對象的<code>target</code>建立并啟動新線程。
調用<code>futuretask</code>對象的<code>get()</code>方法來獲得子線程執行結束後的傳回值。
通過繼承thread類或實作runnable、callable接口都可以實作多線程。不過實作runnable和實作callable的方式基本相同,隻不過callable有傳回值,并可以抛出異常。是以把runnable、callable歸為一類。這種實作方式和繼承thread方式的差别如下:
顯示隻是實作了<code>runnable</code>和<code>callable</code>接口,還可以實作其他的繼承其他的類。
這種情況下, 多線程可以共享同一個<code>target</code>對象,非常适合多個相同線程來處理同一份資源,進而可以更好的将cpu、代碼和資料分開,形成清晰的模型,很好的展現了面向對象的思想。
劣勢:程式設計比較複雜,而且如果想要通路目前線程的話,必須使用<code>thread.currentthread()</code>方法。
優勢:編寫簡單,如果需要通路目前線程,不需要用<code>thread.currentthread()</code>方法,直接使用<code>this</code>即可擷取目前線程。
劣勢:因為線程已經繼承了thread類,是以不能再繼承其他父類。
綜上分析:推薦使用實作runnable接口、callable接口的方式來實作多線程。