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

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
thread.join()用法及例子
一、在研究join的用法之前,先明確兩件事情。
1.join方法定義在Thread類中,則調(diào)用者必須是一個線程,
例如:
Thread t = new CustomThread();//這里一般是自定義的線程類
t.start();//線程起動
t.join();//此處會拋出InterruptedException異常
2.上面的兩行代碼也是在一個線程里面執(zhí)行的。
以上出現(xiàn)了兩個線程,一個是我們自定義的線程類,我們實現(xiàn)了run方法,做一些我們需要的工作;另外一個線程,生成我們自定義線程類的對象,然后執(zhí)行
customThread.start();
customThread.join();
在這種情況下,兩個線程的關(guān)系是一個線程由另外一個線程生成并起動,所以我們暫且認(rèn)為第一個線程叫做“子線程”,另外一個線程叫做“主線程”。
二、為什么要用join()方法
主線程生成并起動了子線程,而子線程里要進(jìn)行大量的耗時的運(yùn)算(這里可以借鑒下線程的作用),當(dāng)主線程處理完其他的事務(wù)后,需要用到子線程的處理結(jié)果,這個時候就要用到j(luò)oin();方法了。
三、join方法的作用
在網(wǎng)上看到有人說“將兩個線程合并”。這樣解釋我覺得理解起來還更麻煩。不如就借鑒下API里的說法:
“等待該線程終止。”
解釋一下,是主線程(我在“一”里已經(jīng)命名過了)等待子線程的終止。也就是在子線程調(diào)用了join()方法后面的代碼,只有等到子線程結(jié)束了才能執(zhí)行。(Waits for this thread to die.)
四、用實例來理解
寫一個簡單的例子來看一下join()的用法,一共三個類:
1.CustomThread 類
2. CustomThread1類
3. JoinTestDemo 類,main方法所在的類。
代碼1:
package wxhx.csdn2;
/**
*
* @author bzwm
*
*/
class CustomThread1 extends Thread {
public CustomThread1() {
super("[CustomThread1] Thread");
};
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " loop at " + i);
Thread.sleep(1000);
}
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
class CustomThread extends Thread {
CustomThread1 t1;
public CustomThread(CustomThread1 t1) {
super("[CustomThread] Thread");
this.t1 = t1;
}
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
t1.join();
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
public class JoinTestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
CustomThread1 t1 = new CustomThread1();
CustomThread t = new CustomThread(t1);
try {
t1.start();
Thread.sleep(2000);
t.start();
t.join();//在代碼2里,將此處注釋掉
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!");
}
}
打印結(jié)果:
main start.//main方法所在的線程起動,但沒有馬上結(jié)束,因為調(diào)用t.join();,所以要等到t結(jié)束了,此線程才能向下執(zhí)行。
[CustomThread1] Thread start.//線程CustomThread1起動
[CustomThread1] Thread loop at 0//線程CustomThread1執(zhí)行
[CustomThread1] Thread loop at 1//線程CustomThread1執(zhí)行
[CustomThread] Thread start.//線程CustomThread起動,但沒有馬上結(jié)束,因為調(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();阻塞處起動,向下繼續(xù)執(zhí)行的結(jié)果
main end!//線程CustomThread結(jié)束,此線程在t.join();阻塞處起動,向下繼續(xù)執(zhí)行的結(jié)果。
修改一下代碼,得到代碼2:(這里只寫出修改的部分)
public class JoinTestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
CustomThread1 t1 = new CustomThread1();
CustomThread t = new CustomThread(t1);
try {
t1.start();
Thread.sleep(2000);
t.start();
//          t.join();//在代碼2里,將此處注釋掉
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!");
}
}
打印結(jié)果:
main start. // main方法所在的線程起動,但沒有馬上結(jié)束,這里并不是因為join方法,而是因為Thread.sleep(2000);
[CustomThread1] Thread start. //線程CustomThread1起動
[CustomThread1] Thread loop at 0//線程CustomThread1執(zhí)行
[CustomThread1] Thread loop at 1//線程CustomThread1執(zhí)行
main end!// Thread.sleep(2000);結(jié)束,雖然在線程CustomThread執(zhí)行了t1.join();,但這并不會影響到其他線程(這里main方法所在的線程)。
[CustomThread] Thread start. //線程CustomThread起動,但沒有馬上結(jié)束,因為調(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();阻塞處起動,向下繼續(xù)執(zhí)行的結(jié)果
五、從源碼看join()方法
在CustomThread的run方法里,執(zhí)行了t1.join();,進(jìn)入看一下它的JDK源碼:
public final void join() throws InterruptedException {
n(0);
}
public final void join() throws InterruptedException {
join(0);
}
然后進(jìn)入join(0)方法:
/**
* Waits at most <code>millis</code> milliseconds for this thread to
* die. A timeout of <code>0</code> means to wait forever. //注意這句
*
* @param      millis   the time to wait in milliseconds.
* @exception  InterruptedException if another thread has interrupted
*             the current thread.  The <i>interrupted status</i> of the
*             current thread is cleared when this exception is thrown.
*/
public final synchronized void join(long millis) //參數(shù)millis為0.
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {//進(jìn)入這個分支
while (isAlive()) {//判斷本線程是否為活動的。這里的本線程就是t1.
wait(0);//阻塞
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
/**
* Waits at most <code>millis</code> milliseconds for this thread to
* die. A timeout of <code>0</code> means to wait forever. //注意這句
*
* @param      millis   the time to wait in milliseconds.
* @exception  InterruptedException if another thread has interrupted
*             the current thread.  The <i>interrupted status</i> of the
*             current thread is cleared when this exception is thrown.
*/
public final synchronized void join(long millis) //參數(shù)millis為0.
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {//進(jìn)入這個分支
while (isAlive()) {//判斷本線程是否為活動的。這里的本線程就是t1.
wait(0);//阻塞
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
單純從代碼上看,如果線程被生成了,但還未被起動,調(diào)用它的join()方法是沒有作用的。將直接繼續(xù)向下執(zhí)行,這里就不寫代碼驗證了。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
深入淺出Java多線程(1)-方法 join
并發(fā)編程之:CountDownLatch
Java 并發(fā)編程:線程間的協(xié)作(wait/notify/sleep/yield/join)
JAVA多線程中join()方法的詳細(xì)分析
一篇文章帶你徹底搞懂join的用法
java程序員修煉之路線程篇九:join和sleep
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服