Thread是學習我們學習多線程接觸到的第一個有關多線程的類,相信每一個學習過或者瞭解過Java多線程的小伙伴都知道Thread類。這次分享主要對Thread的start方法進行講解。 相信大家都知道,start方法是啟動一個線程,並且該線程進入了可執行狀態。在實際的編碼中,我們是重寫run()方法 ...
Thread是學習我們學習多線程接觸到的第一個有關多線程的類,相信每一個學習過或者瞭解過Java多線程的小伙伴都知道Thread類。這次分享主要對Thread的start方法進行講解。
相信大家都知道,start方法是啟動一個線程,並且該線程進入了可執行狀態。在實際的編碼中,我們是重寫run()方法,調用start()方法啟動線程,那麼run()和start()方法有什麼聯繫呢?下麵我們就詳細說說。
一、源碼分析
首先我們查看start的源碼,如下:
/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() */ 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()方法是非常簡單的,如果從上面單獨看上面源碼是看不出任何端倪的,不過我們可以看出來Thread被創建之後,threadStatus這個內部屬性的值是0 。在上面源碼中,最核心的部分就是start0();這個本地方法,也就是我們經常能在其他博文中看到的JNI方法,所謂JNI方法其實沒有那麼高大上,其實JNI就是Java平臺用於和本地C代碼進行互操作的API,JNI不支持Java類和 C++類之間的任何映射機制,這裡只是簡單的提一句。為什麼說start0();是最核心的部分呢?看下圖:
那麼我們重寫的run方法是何時被調用的呢?可以看start方法的註釋,如下圖:
Causes this thread to begin execution; the Java Virtual Machine calls the <code>run</code> method of this thread.
這段註釋是說:在開始執行這個線程時,JVM就會調用run方法,也就是說run方法就是被JNI方法start0調用的。
通過源碼總結要點:
-
Thread被構建後的NEW狀態下,threadStatus這個內部屬性值為0;
-
不能兩次啟動Thread,不然就會出現IllegalThreadStateException異常;
-
group.threadStartFailed(this);可以看出線程啟動後將會被加入到一個ThreadGroup中;
-
一個線程生命周期到了TERMINATED狀態,是不允許調用start方法的。
總結:jdk對start和run的設計,其實就是一個典型的模板模式,也就是父類編寫演算法結構代碼,具體的邏輯實現由子類去完成。
獲取實時信息,關註公眾號:『編程之藝術』,二維碼: