Java面試掛線上程建立後續,不要再被八股文誤導了!建立執行緒的方式只有1種

JavaBuild發表於2024-03-08

寫在開頭

在上篇博文中我們提到小夥伴去面試,面試官讓說出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()方法,又沒有建立執行緒,那它們究竟做了什麼呢?
這個直接給出答案:他們經過重寫,確定了執行緒體,那執行緒體與執行緒又有何區別?我們來看看文心一言怎麼說。
image

總結一句話:執行緒體是執行緒的核心部分,負責執行執行緒的具體任務。

所以說無論是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哥!

image

如果您想與Build哥的關係更近一步,還可以關注“JavaBuild888”,在這裡除了看到《Java成長計劃》系列博文,還有提升工作效率的小筆記、讀書心得、大廠面經、人生感悟等等,歡迎您的加入!

image

相關文章