寫在開頭
在上篇博文中我們提到小夥伴去面試,面試官讓說出8種執行緒建立的方式,而他只說出了4種,導致面試掛掉,在博文中也給出了10種執行緒建立的方式,但在文章的結尾我們提出:真正建立執行緒的方式只有1種,剩下的衍生品多是套殼,那麼在這篇文章中,我們來解釋一下緣由!
執行緒建立方式可先閱讀這篇文章:面試官讓說出8種建立執行緒的方式,我只說了4種,然後掛了。。。
執行緒建立之源
OK!咱們閒話少敘,直接進入正題,回顧一下透過實現Runnable介面,重寫run方法建立執行緒的方式,真的可以建立一個執行緒嗎?來看下面這段demo。
【程式碼示例1】
public class Test implements Runnable{
public static void main(String[] args) {
Test test = new Test();
test.run();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+"runnable執行緒");
}
}
輸出:
main:runnable執行緒
雖然這裡我們實現了Runnable介面並重寫了run方法,但執行結果中輸出的執行緒卻是主執行緒,這可我們呼叫普通的方法一樣,仍舊依靠的主執行緒驅動,那怎麼樣建立一個執行緒呢?
【程式碼示例2】
public class Test implements Runnable{
public static void main(String[] args) {
Test test = new Test();
new Thread(test).start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+"runnable執行緒");
}
}
輸出:
Thread-0:runnable執行緒
這個demo中,我們在外面套了一層Thread,然後呼叫start方法,最終輸出的結果就是一個全新的Thread-0執行緒,從而實現了執行緒的建立。
得出結論
我們繼續換Callable、FutureTask、ThreadGroup、匿名內部類或Lambda表示式等類或介面,發現均無法直接建立一個執行緒,必須藉助Thread的start();
而例如ExecutorService執行緒池、ForkJoin執行緒池、CompletableFuture類、Timer定時器類、parallelStream並行流等等,如果有去看過它們原始碼的小夥伴應該清楚,它們最終都依賴於Thread.start()方法建立執行緒。
因此,我們在這裡可以大膽的得出這樣的一個結論:
在Java中建立執行緒的方式只有一種:透過Thread.start()呼叫 start()方法,會啟動一個執行緒並使執行緒進入就緒狀態,當分配到時間片後開始執行。 start() 會執行執行緒的相應準備工作,然後自動執行 run() 方法的內容。
執行緒體與執行緒的區別
文章寫到這裡,我們一起再來思考一個問題,既然Runnable和Callable介面和Thread類一樣需要重寫他們提供的run()/call()方法,又沒有建立執行緒,那它們究竟做了什麼呢?
這個直接給出答案:他們經過重寫,確定了執行緒體,那執行緒體與執行緒又有何區別?我們來看看文心一言怎麼說。
總結一句話:執行緒體是執行緒的核心部分,負責執行執行緒的具體任務。
所以說無論是Thread中的run還是Runnable中的run,Callable中的call方法,內部所實現的都是執行緒需要執行的具體內容也就是執行緒體。
總結
基於以上的分析,若我們在面試中再次遇到:“Java執行緒有幾種建立方式?”的考題,就可以這樣回答啦:
Java中建立執行緒的方式有很多種,在《Java技術卷》和《Java程式設計思想》中提供了實現Runnable、Callable介面、繼承Thread類、建立執行緒池這四種常見方式,我們還可以透過ForkJoin執行緒池、CompletableFuture類、Timer定時器類、parallelStream並行流、匿名內部類或Lambda表示式等多種方式去實現,但這些都不是真正意義上的建立執行緒,嚴格意義上,Java建立執行緒的方式只有一種那就是透過new Thread().start()建立,Runnable、Callable介面只是重寫了執行緒的執行緒體,用來確定我們執行緒需要執行的內容。
結尾彩蛋
如果本篇部落格對您有一定的幫助,大家記得留言+點贊+收藏呀。原創不易,轉載請聯絡Build哥!
如果您想與Build哥的關係更近一步,還可以關注“JavaBuild888”,在這裡除了看到《Java成長計劃》系列博文,還有提升工作效率的小筆記、讀書心得、大廠面經、人生感悟等等,歡迎您的加入!