日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

浅析 Java Thread.join()

發(fā)布時(shí)間:2025/5/22 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析 Java Thread.join() 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、在研究join的用法之前,先明確兩件事情。

1.join方法定義在Thread類中,則調(diào)用者必須是一個(gè)線程,

例如:

Thread t = new CustomThread();//這里一般是自定義的線程類

t.start();//線程起動(dòng)

t.join();//此處會(huì)拋出InterruptedException異常

?

2.上面的兩行代碼也是在一個(gè)線程里面執(zhí)行的。

?

以上出現(xiàn)了兩個(gè)線程,一個(gè)是我們自定義的線程類,我們實(shí)現(xiàn)了run方法,做一些我們需要的工作;另外一個(gè)線程,生成我們自定義線程類的對(duì)象,然后執(zhí)行

customThread.start();

customThread.join();

在這種情況下,兩個(gè)線程的關(guān)系是一個(gè)線程由另外一個(gè)線程生成并起動(dòng),所以我們暫且認(rèn)為第一個(gè)線程叫做“子線程”,另外一個(gè)線程叫做“主線程”。

?

二、為什么要用join()方法

主線程生成并起動(dòng)了子線程,而子線程里要進(jìn)行大量的耗時(shí)的運(yùn)算(這里可以借鑒下線程的作用),當(dāng)主線程處理完其他的事務(wù)后,需要用到子線程的處理結(jié)果,這個(gè)時(shí)候就要用到j(luò)oin();方法了。

?

?

三、join方法的作用

在網(wǎng)上看到有人說“將兩個(gè)線程合并”。這樣解釋我覺得理解起來還更麻煩。不如就借鑒下API里的說法:

“等待該線程終止。”

解釋一下,是主線程(我在“一”里已經(jīng)命名過了)等待子線程的終止。也就是在子線程調(diào)用了join()方法后面的代碼,只有等到子線程結(jié)束了才能執(zhí)行。(Waits for this thread to die.)

?

?

四、用實(shí)例來理解

寫一個(gè)簡(jiǎn)單的例子來看一下join()的用法,一共三個(gè)類:

1.CustomThread 類

2. CustomThread1類

3. JoinTestDemo 類,main方法所在的類。

?

代碼1:

package?wxhx.csdn2;???
?2/**??
?3?*???
?4?*?@author?bzwm??
?5?*??
?6?*/??
?7class?CustomThread1?extends?Thread?{???
?8????public?CustomThread1()?{???
?9????????super("[CustomThread1]?Thread");???
10????};???
11????public?void?run()?{???
12????????String?threadName?=?Thread.currentThread().getName();???
13????????System.out.println(threadName?+?"?start.");???
14????????try?{???
15????????????for?(int?i?=?0;?i?<?5;?i++)?{???
16????????????????System.out.println(threadName?+?"?loop?at?"?+?i);???
17????????????????Thread.sleep(1000);???
18????????????}???
19????????????System.out.println(threadName?+?"?end.");???
20????????}?catch?(Exception?e)?{???
21????????????System.out.println("Exception?from?"?+?threadName?+?".run");???
22????????}???
23????}???
24}???
25class?CustomThread?extends?Thread?{???
26????CustomThread1?t1;???
27????public?CustomThread(CustomThread1?t1)?{???
28????????super("[CustomThread]?Thread");???
29????????this.t1?=?t1;???
30????}???
31????public?void?run()?{???
32????????String?threadName?=?Thread.currentThread().getName();???
33????????System.out.println(threadName?+?"?start.");???
34????????try?{??? 35????????????t1.join();??? 36????????????System.out.println(threadName?+?"?end.");??? 37????????}?catch?(Exception?e)?{??? 38????????????System.out.println("Exception?from?"?+?threadName?+?".run");??? 39????????}??? 40????}??? 41}??? 42public?class?JoinTestDemo?{??? 43????public?static?void?main(String[]?args)?{??? 44????????String?threadName?=?Thread.currentThread().getName();??? 45????????System.out.println(threadName?+?"?start.");??? 46????????CustomThread1?t1?=?new?CustomThread1();??? 47????????CustomThread?t?=?new?CustomThread(t1);??? 48????????try?{??? 49????????????t1.start();??? 50????????????Thread.sleep(2000);??? 51????????????t.start();??? 52????????????t.join();//在代碼2里,將此處注釋掉??? 53????????}?catch?(Exception?e)?{??? 54????????????System.out.println("Exception?from?main");??? 55????????}??? 56????????System.out.println(threadName?+?"?end!");??? 57????}??? 58}


打印結(jié)果:

?

main start.//main方法所在的線程起動(dòng),但沒有馬上結(jié)束,因?yàn)檎{(diào)用t.join();,所以要等到t結(jié)束了,此線程才能向下執(zhí)行。

[CustomThread1] Thread start.//線程CustomThread1起動(dòng)

[CustomThread1] Thread loop at 0//線程CustomThread1執(zhí)行

[CustomThread1] Thread loop at 1//線程CustomThread1執(zhí)行

[CustomThread] Thread start.//線程CustomThread起動(dòng),但沒有馬上結(jié)束,因?yàn)檎{(diào)用t1.join();,所以要等到t1結(jié)束了,此線程才能向下執(zhí)行。

[CustomThread1] Thread loop at 2//線程CustomThread1繼續(xù)執(zhí)行

[CustomThread1] Thread loop at 3//線程CustomThread1繼續(xù)執(zhí)行

[CustomThread1] Thread loop at 4//線程CustomThread1繼續(xù)執(zhí)行

[CustomThread1] Thread end. //線程CustomThread1結(jié)束了

[CustomThread] Thread end.// 線程CustomThread在t1.join();阻塞處起動(dòng),向下繼續(xù)執(zhí)行的結(jié)果

main end!//線程CustomThread結(jié)束,此線程在t.join();阻塞處起動(dòng),向下繼續(xù)執(zhí)行的結(jié)果。

?

修改一下代碼,得到代碼2:(這里只寫出修改的部分)

?

public?class?JoinTestDemo?{???
?2????public?static?void?main(String[]?args)?{???
?3????????String?threadName?=?Thread.currentThread().getName();???
?4????????System.out.println(threadName?+?"?start.");???
?5????????CustomThread1?t1?=?new?CustomThread1();???
?6????????CustomThread?t?=?new?CustomThread(t1);???
?7????????try?{???
?8????????????t1.start();???
?9????????????Thread.sleep(2000);???
10????????????t.start();???
11//??????????t.join();//在代碼2里,將此處注釋掉???
12????????}?catch?(Exception?e)?{???
13????????????System.out.println("Exception?from?main");???
14????????}???
15????????System.out.println(threadName?+?"?end!");???
16????}???
17}


打印結(jié)果:

?

main start. // main方法所在的線程起動(dòng),但沒有馬上結(jié)束,這里并不是因?yàn)閖oin方法,而是因?yàn)門hread.sleep(2000);

[CustomThread1] Thread start. //線程CustomThread1起動(dòng)

[CustomThread1] Thread loop at 0//線程CustomThread1執(zhí)行

[CustomThread1] Thread loop at 1//線程CustomThread1執(zhí)行

main end!// Thread.sleep(2000);結(jié)束,雖然在線程CustomThread執(zhí)行了t1.join();,但這并不會(huì)影響到其他線程(這里main方法所在的線程)。

[CustomThread] Thread start. //線程CustomThread起動(dòng),但沒有馬上結(jié)束,因?yàn)檎{(diào)用t1.join();,所以要等到t1結(jié)束了,此線程才能向下執(zhí)行。

[CustomThread1] Thread loop at 2//線程CustomThread1繼續(xù)執(zhí)行

[CustomThread1] Thread loop at 3//線程CustomThread1繼續(xù)執(zhí)行

[CustomThread1] Thread loop at 4//線程CustomThread1繼續(xù)執(zhí)行

[CustomThread1] Thread end. //線程CustomThread1結(jié)束了

[CustomThread] Thread end. // 線程CustomThread在t1.join();阻塞處起動(dòng),向下繼續(xù)執(zhí)行的結(jié)果

?

?

五、從源碼看join()方法

?

在CustomThread的run方法里,執(zhí)行了t1.join();,進(jìn)入看一下它的JDK源碼:

?

final?void?join()?throws?InterruptedException?{???
2join(0);???
3}??

?

然后進(jìn)入join(0)方法:

???/**??
?2????*?Waits?at?most?<code>millis</code>?milliseconds?for?this?thread?to???
?3????*?die.?A?timeout?of?<code>0</code>?means?to?wait?forever.?//注意這句??
?4????*??
?5????*?@param??????millis???the?time?to?wait?in?milliseconds.??
?6????*?@exception??InterruptedException?if?another?thread?has?interrupted??
?7????*?????????????the?current?thread.??The?<i>interrupted?status</i>?of?the??
?8????*?????????????current?thread?is?cleared?when?this?exception?is?thrown.??
?9????*/??
10???public?final?synchronized?void?join(long?millis)?//參數(shù)millis為0.???
11???throws?InterruptedException?{???
12long?base?=?System.currentTimeMillis();???
13long?now?=?0;???
14if?(millis?<?0)?{???
15???????????throw?new?IllegalArgumentException("timeout?value?is?negative");???
16}???
17if?(millis?==?0)?{//進(jìn)入這個(gè)分支???
18????while?(isAlive())?{//判斷本線程是否為活動(dòng)的。這里的本線程就是t1.???
19????wait(0);//阻塞???
20????}???
21}?else?{???
22????while?(isAlive())?{???
23????long?delay?=?millis?-?now;???
24????if?(delay?<=?0)?{???
25????????break;???
26????}???
27????wait(delay);???
28????now?=?System.currentTimeMillis()?-?base;???
29????}???
30}???
31???}?

?

單純從代碼上看,如果線程被生成了,但還未被起動(dòng),調(diào)用它的join()方法是沒有作用的。將直接繼續(xù)向下執(zhí)行,這里就不寫代碼驗(yàn)證了。

轉(zhuǎn)載于:https://www.cnblogs.com/kabi/p/5242093.html

總結(jié)

以上是生活随笔為你收集整理的浅析 Java Thread.join()的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。