這篇文章給大家介紹Java中線程順序執(zhí)行解析,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
創(chuàng)新互聯(lián),為您提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)站營(yíng)銷推廣、網(wǎng)站開(kāi)發(fā)設(shè)計(jì),對(duì)服務(wù)成都服務(wù)器托管等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)及推廣經(jīng)驗(yàn)。創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司成立于2013年,提供專業(yè)網(wǎng)站制作報(bào)價(jià)服務(wù),我們深知市場(chǎng)的競(jìng)爭(zhēng)激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞心悅目的作品。 與客戶共同發(fā)展進(jìn)步,是我們永遠(yuǎn)的責(zé)任!
調(diào)用Thread的start()方法啟動(dòng)線程時(shí),線程的執(zhí)行順序是不確定的。也就是說(shuō),在同一個(gè)方法中,連續(xù)創(chuàng)建多個(gè)線程后,調(diào)用線程的start()方法的順序并不能決定線程的執(zhí)行順序。
例如,這里,看一個(gè)簡(jiǎn)單的示例程序,如下所示。
package io.binghe.concurrent.lab03; /** * @author binghe * @version 1.0.0 * @description 線程的順序,直接調(diào)用Thread.start()方法執(zhí)行不能確保線程的執(zhí)行順序 */ public class ThreadSort01 { public static void main(String[] args){ Thread thread1 = new Thread(() -> { System.out.println("thread1"); }); Thread thread2 = new Thread(() -> { System.out.println("thread2"); }); Thread thread3 = new Thread(() -> { System.out.println("thread3"); }); thread1.start(); thread2.start(); thread3.start(); } }
在ThreadSort01類中分別創(chuàng)建了三個(gè)不同的線程,thread1、thread2和thread3,接下來(lái),在程序中按照順序分別調(diào)用thread1.start()、thread2.start()和thread3.start()方法來(lái)分別啟動(dòng)三個(gè)不同的線程。
那么,問(wèn)題來(lái)了,線程的執(zhí)行順序是否按照thread1、thread2和thread3的順序執(zhí)行呢?運(yùn)行ThreadSort01的main方法,結(jié)果如下所示。
thread1 thread2 thread3
再次運(yùn)行時(shí),結(jié)果如下所示。
thread1 thread3 thread2
第三次運(yùn)行時(shí),結(jié)果如下所示。
thread2 thread3 thread1
注意:每個(gè)人運(yùn)行的情況可能都不一樣。
可以看到,每次運(yùn)行程序時(shí),線程的執(zhí)行順序可能不同。線程的啟動(dòng)順序并不能決定線程的執(zhí)行順序。
在實(shí)際業(yè)務(wù)場(chǎng)景中,有時(shí),后啟動(dòng)的線程可能需要依賴先啟動(dòng)的線程執(zhí)行完成才能正確的執(zhí)行線程中的業(yè)務(wù)邏輯。此時(shí),就需要確保線程的執(zhí)行順序。那么如何確保線程的執(zhí)行順序呢?
可以使用Thread類中的join()方法來(lái)確保線程的執(zhí)行順序。例如,下面的測(cè)試代碼。
package io.binghe.concurrent.lab03; /** * @author binghe * @version 1.0.0 * @description 線程的順序,Thread.join()方法能夠確保線程的執(zhí)行順序 */ public class ThreadSort02 { public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() -> { System.out.println("thread1"); }); Thread thread2 = new Thread(() -> { System.out.println("thread2"); }); Thread thread3 = new Thread(() -> { System.out.println("thread3"); }); thread1.start(); //實(shí)際上讓主線程等待子線程執(zhí)行完成 thread1.join(); thread2.start(); thread2.join(); thread3.start(); thread3.join(); } }
可以看到,ThreadSort02類比ThreadSort01類,在每個(gè)線程的啟動(dòng)方法下面添加了調(diào)用線程的join()方法。此時(shí),運(yùn)行ThreadSort02類,結(jié)果如下所示。
thread1 thread2 thread3
再次運(yùn)行時(shí),結(jié)果如下所示。
thread1 thread2 thread3
第三次運(yùn)行時(shí),結(jié)果如下所示。
thread1 thread2 thread3
可以看到,每次運(yùn)行的結(jié)果都是相同的,所以,使用Thread的join()方法能夠保證線程的先后執(zhí)行順序。
既然Thread類的join()方法能夠確保線程的執(zhí)行順序,我們就一起來(lái)看看Thread類的join()方法到底是個(gè)什么鬼。
進(jìn)入Thread的join()方法,如下所示。
public final void join() throws InterruptedException { join(0); }
可以看到j(luò)oin()方法調(diào)用同類中的一個(gè)有參join()方法,并傳遞參數(shù)0。繼續(xù)跟進(jìn)代碼,如下所示。
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
可以看到,有一個(gè)long類型參數(shù)的join()方法使用了synchroinzed修飾,說(shuō)明這個(gè)方法同一時(shí)刻只能被一個(gè)實(shí)例或者方法調(diào)用。由于,傳遞的參數(shù)為0,所以,程序會(huì)進(jìn)入如下代碼邏輯。
if (millis == 0) { while (isAlive()) { wait(0); } }
首先,在代碼中以while循環(huán)的方式來(lái)判斷當(dāng)前線程是否已經(jīng)啟動(dòng)處于活躍狀態(tài),如果已經(jīng)啟動(dòng)處于活躍狀態(tài),則調(diào)用同類中的wait()方法,并傳遞參數(shù)0。繼續(xù)跟進(jìn)wait()方法,如下所示。
public final native void wait(long timeout) throws InterruptedException;
可以看到,wait()方法是一個(gè)本地方法,通過(guò)JNI的方式調(diào)用JDK底層的方法來(lái)使線程等待執(zhí)行完成。
需要注意的是,調(diào)用線程的wait()方法時(shí),會(huì)使主線程處于等待狀態(tài),等待子線程執(zhí)行完成后再次向下執(zhí)行。也就是說(shuō),在ThreadSort02類的main()方法中,調(diào)用子線程的join()方法,會(huì)阻塞main()方法的執(zhí)行,當(dāng)子線程執(zhí)行完成后,main()方法會(huì)繼續(xù)向下執(zhí)行,啟動(dòng)第二個(gè)子線程,并執(zhí)行子線程的業(yè)務(wù)邏輯,以此類推。
關(guān)于Java中線程順序執(zhí)行解析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
網(wǎng)頁(yè)題目:Java中線程順序執(zhí)行解析
鏈接URL:http://muchs.cn/article22/pjjecc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、商城網(wǎng)站、、網(wǎng)站策劃、動(dòng)態(tài)網(wǎng)站、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)