首先是多線程的概念:
多線程
多線程是異步的,和單任務不一樣,並不必定按照代碼的執行順序(上圖左)來運行,而是交錯佔用CPU運行(上圖右);app
JAVA多線程有兩種實現方式:一、繼承Thread類; 二、實現Runnable接口異步
其中實現Runnable接口是Java多線程的主要實現方法,由於JAVA的單繼承特性,一旦繼承了Thread類,就不能再繼承別的類。而JAVA類能夠繼承多個接口。
ide
public class Thread extends Thread { @Override public void run(){ //super.run(); 調用父類的run方法 System.out.println("success!"); } } public class Run { public static void main(String[] args) { Thread a = new Thread(); a.start(); System.out.println("end!"); } }
其中 @Override 是JAVA註解,代碼重寫一個父類的函數,繼承Thread類實現多線程,必須重寫 run() 方法。函數
問題一:爲何要寫 super.run();既然是重寫父類的 run() 方法爲何還要寫 super.run() 呢?ui
首先是 Thread run()方法 源碼:this
//Thread類重寫了Runnable接口的run()方法。
//該run()方法首先判斷當前是否有Runnable的實現target存在。 若是存在就執行target.run()
private Runnable target;
@Override
public void run() {
if (target != null) {
target.run();
}
}
原來Thread類也是實現了Runnable接口;在run()方法中,首先會檢查target是否爲空,若是不是,則執行該target的run()方法。spa
首先上結論:.net
一、無論傳入的Target是否爲空,首先都會執行Thread本身的run()方法。若是重寫了該方法且該方法中沒有super.run(),那麼是永遠不會調用Runnable實現的run()方法;線程
二、若是沒有重寫該方法,則會去判斷target是否爲空,以此來決定調用target實現的run()方法;
三、若是重寫了該方法,且該方法中有super.run(),在執行完該語句以前的全部代碼後,會判斷target是否爲空,以此來決定調用target實現的run()方法
具體實驗: https://blog.csdn.net/guguituzi/article/details/44593863
因此,super.run();正常狀況下能夠不寫,可是我看到是書上都習慣性帶上 super.run() ,知道爲何的小夥伴很是感謝可以給我留言告訴我答案。
問題二: .start() 源碼
/* JVM調用此線程的run方法。*/ 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(); /* 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(); 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 */ } } }
另外,線程名.start() 的順序,不表明線程的執行順序!
public class Thread_2 implements Runnable{ @Override public void run(){ System.out.println("i'm running!..."); } }
實現原理和繼承Thread相似,再也不贅述。