从Thread.start()方法看Thread源码,多次start一个线程会怎么样
生活随笔
收集整理的這篇文章主要介紹了
从Thread.start()方法看Thread源码,多次start一个线程会怎么样
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這篇文章作為Thread類源碼剖析的補充,從一個側面來看Thread源碼。也解答了面試高頻問題:“多次start一個線程會怎么樣?”
答案是:java.lang.IllegalThreadStateException?? 線程狀態非法異常 ? 繼承關系是:--->extends IllegalArgumentException--->extends RuntimeException一個運行時異常,下面我們從源碼來透徹分析一下start()時做了什么。
1 /**2 * Causes this thread to begin execution; the Java Virtual Machine3 * calls the <code>run</code> method of this thread.4 * <p>線程被執行,JVM調用run方法5 * The result is that two threads are running concurrently: the6 * current thread (which returns from the call to the7 * <code>start</code> method) and the other thread (which executes its8 * <code>run</code> method).9 * <p> 10 * It is never legal to start a thread more than once.多次調用start方法啟動一個線程是非法的 11 * In particular, a thread may not be restarted once it has completed 12 * execution. 13 * 14 * @exception IllegalThreadStateException if the thread was already已經啟動的線程再次start,異常 15 * started. 16 * @see #run() 17 * @see #stop() 18 */ 19 public synchronized void start() { 20 /** 21 * This method is not invoked for the main method thread or "system" 22 * group threads created/set up by the VM. Any new functionality added 23 * to this method in the future may have to also be added to the VM. 24 * 25 * A zero status value corresponds to state "NEW". 26 */ 27 if (threadStatus != 0)//狀態校驗 0:NEW 新建狀態 28 throw new IllegalThreadStateException(); 29 30 /* Notify the group that this thread is about to be started 31 * so that it can be added to the group's list of threads 32 * and the group's unstarted count can be decremented. */ 33 group.add(this);//添加進線程組 34 35 boolean started = false; 36 try { 37 start0();//調用native方法執行線程run方法 38 started = true; 39 } finally { 40 try { 41 if (!started) { 42 group.threadStartFailed(this);//啟動失敗,從線程組中移除當前前程。 43 } 44 } catch (Throwable ignore) { 45 /* do nothing. If start0 threw a Throwable then 46 it will be passed up the call stack */ 47 } 48 } 49 } 50 51 private native void start0();greop.add(this),把當前線程添加進線程組,源碼如下:
1 /**2 * Adds the specified thread to this thread group.3 *4 * <p> Note: This method is called from both library code5 * and the Virtual Machine. It is called from VM to add6 * certain system threads to the system thread group.7 *8 * @param t9 * the Thread to be added 10 * 11 * @throws IllegalThreadStateException 12 * if the Thread group has been destroyed 13 */ 14 void add(Thread t) { 15 synchronized (this) { 16 if (destroyed) {//線程組狀態校驗 17 throw new IllegalThreadStateException(); 18 } 19 if (threads == null) { 20 threads = new Thread[4];//初始化長度為4的Thread數組 21 } else if (nthreads == threads.length) {//數組滿了就擴容2倍 22 threads = Arrays.copyOf(threads, nthreads * 2); 23 } 24 threads[nthreads] = t;//新線程t添加進數組 25 26 // This is done last so it doesn't matter in case the 27 // thread is killed 28 nthreads++;//線程數加1 29 30 // The thread is now a fully fledged member of the group, even 31 // though it may, or may not, have been started yet. It will prevent 32 // the group from being destroyed so the unstarted Threads count is 33 // decremented. 34 nUnstartedThreads--;//未啟動線程數-1 35 } 36 }啟動失敗后調用group.threadStartFailed(this),都是加鎖方法,從線程組中移除當前線程,源碼如下
1 void threadStartFailed(Thread t) {2 synchronized(this) {3 remove(t);//移除線程t4 nUnstartedThreads++;//未啟動線程+15 }6 }7 8 private void remove(Thread t) {9 synchronized (this) { 10 if (destroyed) { 11 return; 12 } 13 for (int i = 0 ; i < nthreads ; i++) { 14 if (threads[i] == t) { 15 System.arraycopy(threads, i + 1, threads, i, --nthreads - i); 16 // Zap dangling reference to the dead thread so that 17 // the garbage collector will collect it. 18 threads[nthreads] = null; 19 break; 20 } 21 } 22 } 23 }總結
以上是生活随笔為你收集整理的从Thread.start()方法看Thread源码,多次start一个线程会怎么样的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Thread类源码剖析
- 下一篇: Spring的OncePerReques