欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Java中啟動線程的正確和錯誤方式是什么

這篇文章將為大家詳細(xì)講解有關(guān)Java中啟動線程的正確和錯誤方式是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)公司為您提適合企業(yè)的網(wǎng)站設(shè)計?讓您的網(wǎng)站在搜索引擎具有高度排名,讓您的網(wǎng)站具備超強的網(wǎng)絡(luò)競爭力!結(jié)合企業(yè)自身,進行網(wǎng)站設(shè)計及把握,最后結(jié)合企業(yè)文化和具體宗旨等,才能創(chuàng)作出一份性化解決方案。從網(wǎng)站策劃到做網(wǎng)站、網(wǎng)站設(shè)計, 我們的網(wǎng)頁設(shè)計師為您提供的解決方案。

細(xì)品 Java 中啟動線程的正確和錯誤方式

start 方法和 run 方法的比較

代碼演示:

/**
 * <p>
 * start() 和 run() 的比較
 * </p>
 *
 * @author 踏雪彡尋梅
 * @version 1.0
 * @date 2020/9/20 - 16:15
 * @since JDK1.8
 */public class StartAndRunMethod {    public static void main(String[] args) {        // run 方法演示
        // 輸出: name: main
        // 說明由主線程去執(zhí)行的, 不符合新建一個線程的本意
        Runnable runnable = () -> {
            System.out.println("name: " + Thread.currentThread().getName());
        };
        runnable.run();        // start 方法演示
        // 輸出: name: Thread-0
        // 說明新建了一個線程, 符合本意
        new Thread(runnable).start();
    }
}復(fù)制代碼

從以上示例可以分析出以下兩點:

  • 直接使用 run 方法不會啟動一個新線程。(錯誤方式)

  • start 方法會啟動一個新線程。(正確方式)

start 方法分析

start 方法的含義以及注意事項

  • start 方法可以啟動一個新線程。

    • 線程對象在初始化之后調(diào)用了 start 方法之后, 當(dāng)前線程(通常是主線程)會請求 JVM 虛擬機如果有空閑的話來啟動一下這邊的這個新線程。
    • 也就是說, 啟動一個新線程的本質(zhì)就是請求 JVM 來運行這個線程。
    • 至于這個線程何時能夠運行,并不是簡單的由我們能夠決定的,而是由線程調(diào)度器去決定的。
    • 如果它很忙,即使我們運行了 start 方法,也不一定能夠立刻的啟動線程。
    • 所以說 srtart 方法調(diào)用之后,并不意味這個方法已經(jīng)開始運行了。它可能稍后才會運行,也很有可能很長時間都不會運行,比如說遇到了饑餓的情況。
    • 這也就印證了有些情況下,線程 1 先掉用了 start 方法,而線程 2 后調(diào)用了 start 方法,卻發(fā)現(xiàn)線程 2 先執(zhí)行線程 1 后執(zhí)行的情況。
    • 總結(jié): 調(diào)用 start 方法的順序并不能決定真正線程執(zhí)行的順序。
    • 注意事項
      • start 方法會牽扯到兩個線程。
      • 第一個就是主線程,因為我們必須要有一個主線程或者是其他的線程(哪怕不是主線程)來執(zhí)行這個 start 方法,第二個才是新的線程。
      • 很多情況下會忽略掉為我們創(chuàng)建線程的這個主線程,不要誤以為調(diào)用了 start 就已經(jīng)是子線程去執(zhí)行了,這個語句其實是主線程或者說是父線程來執(zhí)行的,被執(zhí)行之后才去創(chuàng)建新線程。
  • start 方法創(chuàng)建新線程的準(zhǔn)備工作

    • 首先,它會讓自己處于就緒狀態(tài)。
      • 就緒狀態(tài)指已經(jīng)獲取到除了 CPU 以外的其他資源, 如已經(jīng)設(shè)置了上下文、棧、線程狀態(tài)以及 PC(PC 是一個寄存器,PC 指向程序運行的位置) 等。
    • 做完這些準(zhǔn)備工作之后,就萬事俱備只欠東風(fēng)了,東風(fēng)就是 CPU 資源。
    • 做完準(zhǔn)備工作之后,線程才能被 JVM 或操作系統(tǒng)進一步去調(diào)度到執(zhí)行狀態(tài)等待獲取 CPU 資源,然后才會真正地進入到運行狀態(tài)執(zhí)行 run 方法中的代碼。
  • 需要注意: 不能重復(fù)的執(zhí)行 start 方法

    • 代碼示例

      /**
      * <p>
      * 演示不能重復(fù)的執(zhí)行 start 方法(兩次及以上), 否則會報錯
      * </p>
      *
      * @author 踏雪彡尋梅
      * @version 1.0
      * @date 2020/9/20 - 16:47
      * @since JDK1.8
      */public class CantStartTwice {    public static void main(String[] args) {
              Runnable runnable = () -> {
                  System.out.println("name: " + Thread.currentThread().getName());
              };
              Thread thread = new Thread(runnable);        // 輸出: name: Thread-0
              thread.start();        // 輸出: 拋出 java.lang.IllegalThreadStateException
              // 即非法線程狀態(tài)異常(線程狀態(tài)不符合規(guī)定)
              thread.start();
          }
      }復(fù)制代碼
    • 報錯的原因

      • start 一旦開始執(zhí)行,線程狀態(tài)就從最開始的 New 狀態(tài)進入到后續(xù)的狀態(tài),比如說 Runnable,然后一旦線程執(zhí)行完畢,線程就會變成終止?fàn)顟B(tài),而終止?fàn)顟B(tài)永遠(yuǎn)不可能再返回回去,所以會拋出以上異常,也就是說不能回到初始狀態(tài)了。這里描述的還不夠清晰,讓我們來看看源碼能了解的更透徹。

start 方法源碼分析

源碼
public synchronized void start() {    /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
     */
    // 第一步, 檢查線程狀態(tài)是否為初始狀態(tài), 這里也就是上面拋出異常的原因
    if (threadStatus != 0)        throw new IllegalThreadStateException();    /* Notify the group that this thread is about to be started
     * so that it can be added to the group's list of threads
     * and the group's unstarted count can be decremented. */
    // 第二步, 加入線程組
    group.add(this);    boolean started = false;    try {        // 第三步, 調(diào)用 start0 方法
        start0();
        started = true;
    } finally {        try {            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {            /* do nothing. If start0 threw a Throwable then
              it will be passed up the call stack */
        }
    }
}復(fù)制代碼
源碼中的流程

第一步:啟動新線程時會首先檢查線程狀態(tài)是否為初始狀態(tài), 這也是以上拋出異常的原因。即以下代碼:

if (threadStatus != 0)    throw new IllegalThreadStateException();復(fù)制代碼

其中 threadStatus 這個變量的注釋如下,也就是說 Java 的線程狀態(tài)最初始(還沒有啟動)的時候表示為 0:

/* Java thread status for tools,
 * initialized to indicate thread 'not yet started'
 */private volatile int threadStatus = 0;復(fù)制代碼

第二步:將其加入線程組。即以下代碼:

group.add(this);復(fù)制代碼

第三步:最后調(diào)用 start0() 這個 native 方法(native 代表它的代碼不是由 Java 實現(xiàn)的,而是由 C/C++ 實現(xiàn)的,具體實現(xiàn)可以在 JDK 里面看到,了解即可), 即以下代碼:

boolean started = false;try {    // 第三步, 調(diào)用 start0 方法
    start0();
    started = true;
} finally {    try {        if (!started) {
            group.threadStartFailed(this);
        }
    } catch (Throwable ignore) {        /* do nothing. If start0 threw a Throwable then
          it will be passed up the call stack */
    }
}復(fù)制代碼

run 方法分析

run 方法源碼分析

@Overridepublic void run() {    // 傳入了 target 對象(即 Runnable 接口的實現(xiàn)), 執(zhí)行傳入的 target 對象的 run 方法
    if (target != null) {
        target.run();
    }
}復(fù)制代碼

對于 run 方法的兩種情況

  • 第一種: 重寫了 Thread 類的 run 方法,Threadrun 方法會失效, 將會執(zhí)行重寫的 run 方法。

  • 第二種: 傳入了 target 對象(即 Runnable 接口的實現(xiàn)),執(zhí)行 Thread 的原有 run 方法然后接著執(zhí)行 target 對象的 run 方法。

  • 總結(jié):

    • run 方法就是一個普通的方法, 上文中直接去執(zhí)行 run 方法也就是相當(dāng)于我們執(zhí)行自己寫的普通方法一樣,所以它的執(zhí)行線程就是我們的主線程。
    • 所以要想真正的啟動線程,不能直接調(diào)用 run 方法,而是要調(diào)用 start 方法,其中可以間接的調(diào)用 run 方法。

關(guān)于Java中啟動線程的正確和錯誤方式是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

名稱欄目:Java中啟動線程的正確和錯誤方式是什么
標(biāo)題網(wǎng)址:http://aaarwkj.com/article20/gdgcco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)站建設(shè)App開發(fā)、網(wǎng)站改版手機網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計
午夜在线观看视频免费| 亚洲欧美日韩午夜在线| 国产三级精品三级专区| 在线激情视频一区二区| 2021最新四虎永久免费| 日本免费一区二区三区的电影啊 | 亚洲熟女少妇淫语高潮| 亚洲综合实力最强的国家| 日韩av在线黄色免费大全| 日韩免费av在线网站| 99国产综合精品女| 熟女亚洲一区精品久久| 免费精品一区二区三区欧美| 日韩在线中文字幕三区| 久久人体午夜激情视频| 国产精品青青草原在线| 久久久久久亚洲精品人妻| 亚洲人妻av一区二区三区| 成年人午夜看片免费网站| 欧美亚洲另类在线第一页| 婷婷久久五月综合激情| 日韩视频 一区 二区| 成人免费中文字幕电影| 日韩有码在线中文字幕| 激情图区亚洲一区二区| 国产乱一伦一性一情一色| 黄色18禁网站在线看| 91麻豆视频福利视频| 未满十八禁在线观看免费| 精品国产一区av在线| 亚洲高清中文字幕专区| 国内不卡一区二区三区| 中文字幕乱码av一区二区| 精品久久久久久久久极品| 中文字幕熟妇人妻av在线| 无遮挡动漫网站免费观看| 国内午夜福利精品视频| 蜜桃精品国产一区二区三区| 欧美国产日韩激情在线| 九九热这里只有免费视频| 亚洲一区二区视频在线播放|