一、join線程的作用
join()方法:Thread提供的讓一個(gè)線程去等待另一個(gè)線程完成因惭。當(dāng)在某個(gè)程序執(zhí)行流中(如main線程)調(diào)用其它線程(如t2線程)的join方法(t2.join())鬼癣,調(diào)用線程(main線程)將被阻塞,直到被join()方法加入的join線程(t2.start())執(zhí)行完成為止。
二、示列代碼分析
1慌随、在沒有join方法的時(shí)候
public class MyJoinTest implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "====" + i);
}
}
public static void main(String[] args) throws InterruptedException {
MyJoinTest myJoinTest = new MyJoinTest();
Thread t1 = new Thread(myJoinTest, "普通線程");
Thread t2 = new Thread(myJoinTest, "join的線程");
t1.start(); //啟動(dòng)t1線程
//下面屬于main主線程
for (int i = 0; i < 10; i++) {
if (i == 5) {
t2.start(); //啟動(dòng)t2線程
}
System.out.println(Thread.currentThread().getName() + "====" + i);
}
}
}
輸出結(jié)果為
main====0
main====1
main====2
main====3
main====4
普通線程====0
普通線程====1
普通線程====2
普通線程====3
普通線程====4
main====5
main====6
main====7
main====8
main====9
join的線程====0
join的線程====1
join的線程====2
join的線程====3
join的線程====4
2、在有join方法的時(shí)候
public class MyJoinTest implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "====" + i);
}
}
public static void main(String[] args) throws InterruptedException {
MyJoinTest myJoinTest = new MyJoinTest();
Thread t1 = new Thread(myJoinTest, "普通線程");
Thread t2 = new Thread(myJoinTest, "join的線程");
t1.start(); //啟動(dòng)t1線程
//下面屬于main主線程
for (int i = 0; i < 10; i++) {
if (i == 5) {
t2.start(); //啟動(dòng)t2線程
//main線程調(diào)用了t2線程的join方法躺同,導(dǎo)致main線程必須等待t2執(zhí)行結(jié)束才可以向下執(zhí)行
t2.join();
}
System.out.println(Thread.currentThread().getName() + "====" + i);
}
}
}
輸出結(jié)果為
main====0
main====1
main====2
main====3
main====4
普通線程====0
普通線程====1
普通線程====2
普通線程====3
普通線程====4
join的線程====0
join的線程====1
join的線程====2
join的線程====3
join的線程====4
main====5
main====6
main====7
main====8
main====9
3、join()方法的源碼
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;
}
}
}
從源碼中可以看到:join方法的原理就是調(diào)用相應(yīng)線程的wait方法進(jìn)行等待操作的丸逸,例如A線程中調(diào)用了B線程的join方法蹋艺,則相當(dāng)于在A線程中調(diào)用了B線程的wait方法,當(dāng)B線程執(zhí)行完(或者到達(dá)等待時(shí)間)黄刚,B線程會(huì)自動(dòng)調(diào)用自身的notifyAll方法喚醒A線程捎谨,從而達(dá)到同步的目的。