国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
同一個(gè)線(xiàn)程多次調(diào)用start()會(huì)出現(xiàn)的問(wèn)題

測(cè)試代碼:

 1 package com.led.test; 2  3 /** 4  * @author Alan 5  * @date 2018/6/18 15:09 6  * @description 測(cè)試同一個(gè)線(xiàn)程多次調(diào)用start()方法 7  */ 8 public class MuchStart implements Runnable{ //實(shí)現(xiàn)Runnable接口 9     public void run() {10         System.out.println(Thread.currentThread().getName() + "is running ...");11     }12 13     public static void main(String[] args) {14         MuchStart muchStart = new MuchStart();15         Thread t = new Thread(muchStart);//創(chuàng)建實(shí)現(xiàn)了Runnable接口的Thread實(shí)例16         t.start();//多次調(diào)用start()方法17         t.start();18         t.start();19     }20 }

測(cè)試結(jié)果:

  線(xiàn)程首先會(huì)運(yùn)行一次,然后拋出java.lang.IllegalThreadStateException異常。

 接下來(lái)深入源碼分析下原因:

  我們根據(jù)控制臺(tái)的異常信息,定位到Thread.java的第708行,也就start()方法內(nèi)部,打個(gè)斷點(diǎn)調(diào)試:

 

   調(diào)試發(fā)現(xiàn),第一個(gè)次運(yùn)行start()方法時(shí),threadStatus是0,此時(shí)if條件不滿(mǎn)足,繼續(xù)執(zhí)行,會(huì)將當(dāng)前線(xiàn)程添加到線(xiàn)程組中去執(zhí)行。第二次運(yùn)行start()方法時(shí),threadStatus變成了2,if條件滿(mǎn)足,于是拋出了java.lang.IllegalThreadStateException異常。

Thread-0is running ...Exception in thread "main" java.lang.IllegalThreadStateException    at java.lang.Thread.start(Thread.java:708)    at com.led.test.MuchStart.main(MuchStart.java:17)

start()源碼進(jìn)行分析

 1 /** 2      * Causes this thread to begin execution; the Java Virtual Machine 3      * calls the <code>run</code> method of this thread.
     讓這個(gè)線(xiàn)程開(kāi)始執(zhí)行。JVM會(huì)調(diào)用這個(gè)線(xiàn)程的run()方法。
4 * <p> 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.一個(gè)線(xiàn)程多次調(diào)用start()方法是非法的。11 * In particular, a thread may not be restarted once it has completed12 * execution.13 *特別說(shuō)明:一個(gè)線(xiàn)程執(zhí)行完后,不太可能重新運(yùn)行。14 * @exception IllegalThreadStateException if the thread was already15 * started.
              如果該線(xiàn)程已經(jīng)啟動(dòng),則再次調(diào)用start()方法,就會(huì)拋出IllegalThreadStateException異常。
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 added23 * 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)//新的線(xiàn)程threadState值是028 throw new IllegalThreadStateException();29 30 /* Notify the group that this thread is about to be started31 * so that it can be added to the group's list of threads32 * and the group's unstarted count can be decremented. */33 group.add(this);//通知線(xiàn)程組該線(xiàn)程將要開(kāi)始運(yùn)行,這樣該線(xiàn)程就會(huì)被添加到線(xiàn)程列表中,此時(shí)列表的unstarted數(shù)將會(huì)減少。34 35 boolean started = false;36 try {37 start0();//調(diào)用原生方法態(tài)方法啟動(dòng)線(xiàn)程38 started = true;//已經(jīng)運(yùn)行的標(biāo)記設(shè)置為true39 } finally {40 try {41 if (!started) {//若開(kāi)始運(yùn)行標(biāo)記未設(shè)置成功,則通知線(xiàn)程組該線(xiàn)程嘗試運(yùn)行失敗42 group.threadStartFailed(this);43 }44 } catch (Throwable ignore) {45 /* do nothing. If start0 threw a Throwable then46 it will be passed up the call stack */47 }48 }49 }

group.add(this)  ---線(xiàn)程組添加線(xiàn)程源碼分析

 1 /** 2      * Adds the specified thread to this thread group. 3      * 添加特定的線(xiàn)程到該線(xiàn)程組 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 added10      *11      * @throws  IllegalThreadStateException12      *          if the Thread group has been destroyed13      */14     void add(Thread t) {15         synchronized (this) {//線(xiàn)程同步16             if (destroyed) {//如果線(xiàn)程組的銷(xiāo)毀標(biāo)記(destroyed)是true,則拋出IllegalThreadStateException17                 throw new IllegalThreadStateException();18             }19             if (threads == null) {//如果線(xiàn)程數(shù)組為空,則初始為4個(gè)新的線(xiàn)程20                 threads = new Thread[4];21             } else if (nthreads == threads.length) {//如果當(dāng)前線(xiàn)程組已滿(mǎn),則擴(kuò)容至原來(lái)的2倍22                 threads = Arrays.copyOf(threads, nthreads * 2);23             }24             threads[nthreads] = t;//將當(dāng)前線(xiàn)程放入線(xiàn)程數(shù)組的末尾25 26             // This is done last so it doesn't matter in case the27             // thread is killed28             nthreads++;//線(xiàn)程數(shù)組元素個(gè)數(shù)+129 30             // The thread is now a fully fledged member of the group, even31             // though it may, or may not, have been started yet. It will prevent32             // the group from being destroyed so the unstarted Threads count is33             // decremented.34             nUnstartedThreads--;//未啟動(dòng)線(xiàn)程數(shù)-135         }36     }

 start0()代碼分析:

1 private native void start0();//原生態(tài)代碼,源碼不在當(dāng)前文件中,調(diào)用的其它文件的代碼(可能是c/c++寫(xiě)的代碼)

threadStartFailed()源碼分析:

 1 /** 2      * Notifies the group that the thread {@code t} has failed 3      * an attempt to start. 4      * 通知線(xiàn)程組該線(xiàn)程嘗試運(yùn)行失敗 5      * <p> The state of this thread group is rolled back as if the 6      * attempt to start the thread has never occurred. The thread is again 7      * considered an unstarted member of the thread group, and a subsequent 8      * attempt to start the thread is permitted. 9      *10      * @param  t11      *         the Thread whose start method was invoked12      */13     void threadStartFailed(Thread t) {14         synchronized(this) {//同步15             remove(t);//從線(xiàn)程組中移除該線(xiàn)程16             nUnstartedThreads++;//未啟動(dòng)線(xiàn)程數(shù)+117         }18     }

 總結(jié):

  同一個(gè)線(xiàn)程只能調(diào)用start()方法一次,多次調(diào)用會(huì)拋出java.lang.IllegalThreadStateException。啟動(dòng)一個(gè)線(xiàn)程,需要調(diào)用start()方法而不是run()方法。此時(shí),當(dāng)前線(xiàn)程會(huì)被添加到線(xiàn)程組中,進(jìn)入就緒狀態(tài),等待線(xiàn)程調(diào)度器的調(diào)用,若獲取到了資源,則能進(jìn)入運(yùn)行狀態(tài),run()方法只是線(xiàn)程體,即線(xiàn)程執(zhí)行的內(nèi)容,若沒(méi)調(diào)用start()方法,run()方法只是一個(gè)普通的方法。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Java中啟動(dòng)線(xiàn)程start和run方法
ocjp題庫(kù)試題詳解(一)
java開(kāi)啟新線(xiàn)程并傳參的兩種方法
java多線(xiàn)程設(shè)計(jì)模式(1) 線(xiàn)程的創(chuàng)建和啟動(dòng)
java學(xué)習(xí)——112.滾動(dòng)字
java多線(xiàn)程之繼承Thread類(lèi)創(chuàng)建線(xiàn)程類(lèi)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服