Java多線程start()方法原理解析
1、為什么啟動(dòng)線程不用run()方法而是使用start()方法
run()方法只是一個(gè)類(lèi)中的普通方法,調(diào)用run方法跟調(diào)用普通方法一樣
而start()是創(chuàng)建線程等一系列工作,然后自己調(diào)用run里面的任務(wù)內(nèi)容。
驗(yàn)證代碼:
/** * @data 2019/11/8 - 下午10:29 * 描述:run()和start() */ public class StartAndRunMethod { public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }; runnable.run(); new Thread(runnable).start(); } }
結(jié)果:
main
Thread-0
2、start()源碼解讀
啟動(dòng)新線程檢查線程狀態(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". */ if (threadStatus != 0) throw new IllegalThreadStateException();
關(guān)于threadStatus源碼:
/* * Java thread status for tools, default indicates thread 'not yet started' */ private volatile int threadStatus;
通過(guò)代碼可以看到就是threadStatus就是記錄Thread的狀態(tài),初始線程默認(rèn)為0.
加入線程組
/* 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);
調(diào)用start0()
boolean started = false; try { 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 */ } } }
start0()方法使用c++編寫(xiě)的方法,這些代碼在gdk代碼中,所以這里不再這里探究了。
3、start()方法不能使用多次
通過(guò)剛剛源碼分析,就知道start方法剛開(kāi)始就檢查線程狀態(tài),當(dāng)線程創(chuàng)建后或結(jié)束了,該狀態(tài)就不同于初始化狀態(tài)就會(huì)拋出IllegalThreadStateException異常。
測(cè)試代碼:
start不可以使用多次
/** * @data 2019/11/8 - 下午11:57 * 描述:start不可以使用多次 */ public class CantStartTwice { public static void main(String[] args) { Thread thread = new Thread(); thread.start(); thread.start(); } }
4、注意點(diǎn):
start方法是被synchronized修飾的方法,可以保證線程安全。
由jvm創(chuàng)建的main方法線程和system組線程,并不會(huì)通過(guò)start來(lái)啟動(dòng)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章

Java編程IP地址和數(shù)字相互轉(zhuǎn)換代碼示例

Spring MVC中基于自定義Editor的表單數(shù)據(jù)處理技巧分享

Mybatis實(shí)現(xiàn)動(dòng)態(tài)SQL編寫(xiě)詳細(xì)代碼示例

Windows環(huán)境下重啟jar服務(wù)bat代碼的解決方案