從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 Machine
 3      * calls the <code>run</code> method of this thread.
 4      * <p>線程被執行,JVM調用run方法
 5      * The result is that two threads are running concurrently: the
 6      * current thread (which returns from the call to the
 7      * <code>start</code> method) and the other thread (which executes its
 8      * <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 code
 5      * and the Virtual Machine. It is called from VM to add
 6      * certain system threads to the system thread group.
 7      *
 8      * @param  t
 9      *         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);//移除線程t
 4             nUnstartedThreads++;//未啟動線程+1
 5         }
 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     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM