欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中為什么start方法不能重復調用而run方法可以?

 更新時間:2022年05月09日 11:39:56   作者:??Java中文社群????  
這篇文章主要介紹了Java中為什么start方法不能重復調用而run方法可以?帶著疑問一起學習下面文章的詳細內容吧

初學線程時,總是將 run 方法和 start 方法搞混,雖然二者是完全不同的兩個方法,但剛開始使用時很難分清,原因就是因為初次使用時效果貌似是一樣的,

如下代碼所示:

public static void main(String[] args) {
    // 創(chuàng)建線程一
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("執(zhí)行線程一");
        }
    });
    // 調用 run 方法
    thread.run();

    // 創(chuàng)建線程二
    Thread thread2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("執(zhí)行線程二");
        }
    });
    // 調用 start 方法
    thread2.start();
}

以上程序的執(zhí)行結果如下: 

 從上述結果可以看出,二者調用之后的執(zhí)行效果都是一樣,都可以成功執(zhí)行任務。但是,如果在執(zhí)行線程的時候,加上打印當前線程的名稱就能看出二者的不同了,

如下代碼所示:

public static void main(String[] args) {
    // 創(chuàng)建線程一
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            // 獲取到當前執(zhí)行線程
            Thread currThread = Thread.currentThread();
            System.out.println("執(zhí)行線程一,線程名:" + currThread.getName());
        }
    });
    // 調用 run 方法
    thread.run();

    // 創(chuàng)建線程二
    Thread thread2 = new Thread(new Runnable() {
        @Override
        public void run() {
            // 獲取到當前執(zhí)行線程
            Thread currThread = Thread.currentThread();
            System.out.println("執(zhí)行線程二,線程名:" + currThread.getName());
        }
    });
    // 調用 start 方法
    thread2.start();
}

以上程序的執(zhí)行結果如下: 

 從上述結果我們可以看出:當調用 run 方法時,其實是調用當前主程序 main 來執(zhí)行方法體的;而調用 start 方法才是真正的創(chuàng)建一個新線程來執(zhí)行任務。

區(qū)別1

run 方法和 start 方法的第一個區(qū)別是:調用 start 方法是真正開啟一個線程來執(zhí)行任務,而調用 run 方法相當于執(zhí)行普通方法 run,并不會開啟新線程,

如下圖所示: 

區(qū)別2

run 方法和 start 方法的第二個區(qū)別是:run 方法也叫做線程體,它里面包含了具體要執(zhí)行的業(yè)務代碼,當調用 run 方法時,會立即執(zhí)行 run 方法中的代碼(如果當前線程時間片未用完);而調用 start 方法時,是啟動一個線程并將線程的狀態(tài)設置為就緒狀態(tài)。也就是說調用 start 方法,并不會立即執(zhí)行。

區(qū)別3

因為 run 方法是普通方法,而普通方法是可以被多次調用的,所以 run 方法可以被調用多次;而 start 方法是創(chuàng)建新線程來執(zhí)行任務,因為線程只能被創(chuàng)建一次,所以它們的第三個區(qū)別是:run 方法可以被調用多次,而 start 方法只能被調用一次。

 測試代碼如下:

// 創(chuàng)建線程一
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        // 獲取到當前執(zhí)行的線程
        Thread currThread = Thread.currentThread();
        System.out.println("執(zhí)行線程一,線程名:" + currThread.getName());
    }
});
// 調用 run 方法
thread.run();
// 多次調用 run 方法
thread.run();

// 創(chuàng)建線程二
Thread thread2 = new Thread(new Runnable() {
    @Override
    public void run() {
        // 獲取到當前執(zhí)行的線程
        Thread currThread = Thread.currentThread();
        System.out.println("執(zhí)行線程二,線程名:" + currThread.getName());
    }
});
// 調用 start 方法
thread2.start();
// 多次調用 start 方法
thread2.start();

以上程序的執(zhí)行結果如下: 

 從上述結果可以看出,run 方法多次調用可用正常執(zhí)行,而第二次調用 start 方法時程序就報錯了,提示“IllegalThreadStateException”非法線程狀態(tài)異常。

為什么start不能被重復調用?

要找到這個問題的答案,就要查看 start 方法的實現(xiàn)源碼,它的源碼如下: 

 從 start 源碼實現(xiàn)的第一行,我們就可以得到問題的答案,因為 start 方法在執(zhí)行時,會先判斷當前線程的狀態(tài)是不是等于 0,也就是是否為新建狀態(tài) NEW,如果不等于新建狀態(tài),那么就會拋出“IllegalThreadStateException”非法線程狀態(tài)異常,這就是線程的 start 方法不能被重復調用的原因。 它的執(zhí)行過程是:當線程調用了第一個 start 方法之后,線程的狀態(tài)就會從新建狀態(tài) NEW,變?yōu)榫途w狀態(tài) RUNNABLE,此時再次調用 start 方法,JVM 就會判斷出當前的線程已經不等于新建狀態(tài),從而拋出 IllegalThreadStateException 非法線程狀態(tài)異常。

總結

run 方法和 start 方法的主要區(qū)別如下:

  • 方法性質不同:run 是一個普通方法,而 start 是開啟新線程的方法。
  • 執(zhí)行速度不同:調用 run 方法會立即執(zhí)行任務,調用 start 方法是將線程的狀態(tài)改為就緒狀態(tài),不會立即執(zhí)行。
  • 調用次數(shù)不同:run 方法可以被重復調用,而 start 方法只能被調用一次。

start 方法之所以不能被重復調用的原因是,線程的狀態(tài)是不可逆的,Thread 在 start 的實現(xiàn)源碼中做了判斷,如果線程不是新建狀態(tài) NEW,則會拋出非法線程狀態(tài)異常 IllegalThreadStateException。?

到此這篇關于Java中為什么start方法不能重復調用而run方法可以?的文章就介紹到這了,更多相關start與run方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java后綴數(shù)組之求sa數(shù)組的實例代碼

    Java后綴數(shù)組之求sa數(shù)組的實例代碼

    后綴數(shù)組就是一個字符串所有后綴大小排序后的一個集合,然后我們根據(jù)后綴數(shù)組的一些性質就可以實現(xiàn)各種需求。這篇文章主要介紹了Java后綴數(shù)組-求sa數(shù)組,需要的朋友可以參考下
    2018-04-04
  • MybatisPlus調用原生SQL的三種方法實例詳解

    MybatisPlus調用原生SQL的三種方法實例詳解

    這篇文章主要介紹了MybatisPlus調用原生SQL的三種方法,在有些情況下需要用到MybatisPlus查詢原生SQL,MybatisPlus其實帶有運行原生SQL的方法,我這里列舉三種,需要的朋友可以參考下
    2022-09-09
  • 淺談java字符串比較到底應該用==還是equals

    淺談java字符串比較到底應該用==還是equals

    這篇文章主要介紹了淺談java字符串比較到底應該用==還是equals,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • shiro之記住登錄信息

    shiro之記住登錄信息

    Shiro提供了記住我(RememberMe)的功能,當關閉瀏覽器時下次再次打開還能記住你的信息,下面小編給大家分享shiro之記住登錄信息的相關知識,感興趣的朋友一起看看吧
    2017-09-09
  • Spring中自動裝配的4種方式

    Spring中自動裝配的4種方式

    今天小編就為大家分享一篇關于Spring中自動裝配的4種方式,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Mybatis持久層框架入門之CRUD實例代碼詳解

    Mybatis持久層框架入門之CRUD實例代碼詳解

    這篇文章主要介紹了Mybatis持久層框架入門之CRUD實例,需要的朋友可以參考下
    2022-05-05
  • 完美解決gson將Integer默認轉換成Double的問題

    完美解決gson將Integer默認轉換成Double的問題

    下面小編就為大家?guī)硪黄昝澜鉀Qgson將Integer默認轉換成Double的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java實現(xiàn)HashMap排序方法的示例詳解

    Java實現(xiàn)HashMap排序方法的示例詳解

    這篇文章主要通過一些示例為大家介紹了Java對HashMap進行排序的方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解一下
    2022-05-05
  • 詳解時間輪TimeWheel的工作原理

    詳解時間輪TimeWheel的工作原理

    時間輪(TimeWheel)作為一種高效率的計時器實現(xiàn)方案,在1987年發(fā)表的論文Hashed?and?Hierarchical?Timing?Wheels中被首次提出。本文主要來聊聊它的工作原理,感興趣的可以了解一下
    2023-02-02
  • eclipse修改jvm參數(shù)調優(yōu)方法(2種)

    eclipse修改jvm參數(shù)調優(yōu)方法(2種)

    本篇文章主要介紹了eclipse修改jvm參數(shù)調優(yōu)方法(2種),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02

最新評論