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

創(chuàng)新互聯(lián)公司為您提適合企業(yè)的網(wǎng)站設計?讓您的網(wǎng)站在搜索引擎具有高度排名,讓您的網(wǎng)站具備超強的網(wǎng)絡競爭力!結合企業(yè)自身,進行網(wǎng)站設計及把握,最后結合企業(yè)文化和具體宗旨等,才能創(chuàng)作出一份性化解決方案。從網(wǎng)站策劃到做網(wǎng)站、網(wǎng)站設計, 我們的網(wǎng)頁設計師為您提供的解決方案。
代碼演示:
/**
* <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();
}
}復制代碼從以上示例可以分析出以下兩點:
直接使用 run 方法不會啟動一個新線程。(錯誤方式)
start 方法會啟動一個新線程。(正確方式)
start 方法可以啟動一個新線程。
start 方法之后, 當前線程(通常是主線程)會請求 JVM 虛擬機如果有空閑的話來啟動一下這邊的這個新線程。start 方法,也不一定能夠立刻的啟動線程。srtart 方法調用之后,并不意味這個方法已經(jīng)開始運行了。它可能稍后才會運行,也很有可能很長時間都不會運行,比如說遇到了饑餓的情況。start 方法,而線程 2 后調用了 start 方法,卻發(fā)現(xiàn)線程 2 先執(zhí)行線程 1 后執(zhí)行的情況。start 方法的順序并不能決定真正線程執(zhí)行的順序。start 方法會牽扯到兩個線程。start 方法,第二個才是新的線程。start 就已經(jīng)是子線程去執(zhí)行了,這個語句其實是主線程或者說是父線程來執(zhí)行的,被執(zhí)行之后才去創(chuàng)建新線程。start 方法創(chuàng)建新線程的準備工作
run 方法中的代碼。需要注意: 不能重復的執(zhí)行 start 方法
代碼示例
/**
* <p>
* 演示不能重復的執(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();
}
}復制代碼報錯的原因
start 一旦開始執(zhí)行,線程狀態(tài)就從最開始的 New 狀態(tài)進入到后續(xù)的狀態(tài),比如說 Runnable,然后一旦線程執(zhí)行完畢,線程就會變成終止狀態(tài),而終止狀態(tài)永遠不可能再返回回去,所以會拋出以上異常,也就是說不能回到初始狀態(tài)了。這里描述的還不夠清晰,讓我們來看看源碼能了解的更透徹。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 { // 第三步, 調用 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 */
}
}
}復制代碼第一步:啟動新線程時會首先檢查線程狀態(tài)是否為初始狀態(tài), 這也是以上拋出異常的原因。即以下代碼:
if (threadStatus != 0) throw new IllegalThreadStateException();復制代碼
其中 threadStatus 這個變量的注釋如下,也就是說 Java 的線程狀態(tài)最初始(還沒有啟動)的時候表示為 0:
/* Java thread status for tools, * initialized to indicate thread 'not yet started' */private volatile int threadStatus = 0;復制代碼
第二步:將其加入線程組。即以下代碼:
group.add(this);復制代碼
第三步:最后調用 start0() 這個 native 方法(native 代表它的代碼不是由 Java 實現(xiàn)的,而是由 C/C++ 實現(xiàn)的,具體實現(xiàn)可以在 JDK 里面看到,了解即可), 即以下代碼:
boolean started = false;try { // 第三步, 調用 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 */
}
}復制代碼@Overridepublic void run() { // 傳入了 target 對象(即 Runnable 接口的實現(xiàn)), 執(zhí)行傳入的 target 對象的 run 方法
if (target != null) {
target.run();
}
}復制代碼第一種: 重寫了 Thread 類的 run 方法,Thread 的 run 方法會失效, 將會執(zhí)行重寫的 run 方法。
第二種: 傳入了 target 對象(即 Runnable 接口的實現(xiàn)),執(zhí)行 Thread 的原有 run 方法然后接著執(zhí)行 target 對象的 run 方法。
總結:
run 方法就是一個普通的方法, 上文中直接去執(zhí)行 run 方法也就是相當于我們執(zhí)行自己寫的普通方法一樣,所以它的執(zhí)行線程就是我們的主線程。run 方法,而是要調用 start 方法,其中可以間接的調用 run 方法。關于Java中啟動線程的正確和錯誤方式是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
名稱欄目:Java中啟動線程的正確和錯誤方式是什么
標題網(wǎng)址:http://chinadenli.net/article20/gdgcco.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)站建設、App開發(fā)、網(wǎng)站改版、手機網(wǎng)站建設、標簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)