start() && run()、Runnable && Callable、Thread && Runnable

線程的定義:“線程是一種輕量級的進程,是由進程派生出來的子任務,它是程序執行的一個路徑;每個線程都有自己的局部變量表、程序計數器(指向真正執行的指令指針)以及各自的生命週期”

start() && run()
要搞清楚這個問題,需要我們明確“線程的執行單元”與“線程”是兩個不同的概念。在JAVA中通過Thread類重寫的run()方法是線程的執行單元,而通過調用start()方法纔是真正啓動了一個線程,start()方法會使得該線程開始執行,java虛擬機會去調用該線程的run()方法

根據java api,Runnable接口只有一個方法,就是run(),start()方法是Thread的類方法

在不少關於JAVA線程的軟文或者書籍中,經常會提到,創建線程有兩種方式:
第一種是構造一個Thread
第二種是實現Runnable接口。
通過上面的分析,這種說法其實是不嚴謹的。在JDK中代表線程的只有Thread類,而Runnable接口只是簡單定義了一個無參數返回值的run方法。而我們知道run方法只是定義了線程的執行單元,而並非直接開啓了線程資源,只有Thread方法的start()方法纔可以啓動一個線程。

所以,如果面試中有人問你在JAVA中實現線程的方式有哪些?應該告訴他準確答案:“在JAVA中創建線程只有一種方式,那就是構造Thread類。而實現線程的執行單元則有兩種方式,第一種是重寫Thread類的run方法;第二種是實現Runnable接口的run方法,並且將Runnable實例用作構造Thread的參數”

Runnable && Callable
相同點

兩者都是接口;(廢話)
兩者都可用來編寫多線程程序;
兩者都需要調用Thread.start()啓動線程;

不同點

兩者最大的不同點是:實現Callable接口的任務線程能返回執行結果;而實現Runnable接口的任務線程不能返回結果;
Callable接口的call()方法允許拋出異常;而Runnable接口的run()方法的異常只能在內部消化,不能繼續上拋;

Thread && Runnable

1、效果上沒區別,寫法上的區別而已。
2、沒有可比性,Thread實現了Runnable接口並進行了擴展,我們通常拿來進行比較只是寫法上的比較,而Thread和Runnable的實質是實現的關係,不是同類東西。

  • Runnable適合多個相同的程序代碼的線程去處理同一個資源;
  • 可以避免Java中的單繼承的限制,增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立
  • 線程池只能放入實現Runnable 類線程,不能直接放入繼承Thread的類

注意點:
Callable接口支持返回執行結果,此時需要調用FutureTask.get()方法實現,此方法會阻塞主線程直到獲取‘將來’結果;當不調用此方法時,主線程不會阻塞

參考 :線程池的設計原理是什麼?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章