join()
方法意味着等待當前線程執行完,主線程才能繼續往下執行。 也就是將當前線程加入到主線程中。
例如下面的例子:我們將ts1
加入到主線程,看看會發生什麼結果?
package testthread;
public class TestStart extends Thread{
String name;
public TestStart(String name) {
this.name = name;
}
public void run() {
System.out.println(Thread.currentThread().getName()+"線程開始");
for(int i = 0; i<10; i++) {
System.out.println(name+"運行"+i);
try {
Thread.sleep((int) Math.random()*10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"線程結束");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"線程開始");
// TODO Auto-generated method stub
TestStart ts1 = new TestStart("A");
TestStart ts2 = new TestStart("B");
ts1.start();
try {
ts1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ts2.start();
System.out.println(Thread.currentThread().getName()+"線程結束");
}
}
運行結果如下:
main線程開始
Thread-0線程開始
A運行0
A運行1
A運行2
A運行3
A運行4
A運行5
A運行6
A運行7
A運行8
A運行9
Thread-0線程結束
main線程結束
Thread-1線程開始
B運行0
B運行1
B運行2
B運行3
B運行4
B運行5
B運行6
B運行7
B運行8
B運行9
Thread-1線程結束
Thread-0
等價於A
,Thread-1
等價於B
。ts1
使用join()
方法之後,main
開始之後等待Thread-0
結束。由於ts2
沒有使用join()
方法,所以最後執行。下來再看看給ts2
使用join()
方法之後是什麼結果?
package testthread;
public class TestStart extends Thread{
String name;
public TestStart(String name) {
this.name = name;
}
public void run() {
System.out.println(Thread.currentThread().getName()+"線程開始");
for(int i = 0; i<10; i++) {
System.out.println(name+"運行"+i);
try {
Thread.sleep((int) Math.random()*10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"線程結束");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"線程開始");
// TODO Auto-generated method stub
TestStart ts1 = new TestStart("A");
TestStart ts2 = new TestStart("B");
ts1.start();
try {
ts1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ts2.start();
try {
ts2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"線程結束");
}
}
運行結果如下:
main線程開始
Thread-0線程開始
A運行0
A運行1
A運行2
A運行3
A運行4
A運行5
A運行6
A運行7
A運行8
A運行9
Thread-0線程結束
Thread-1線程開始
B運行0
B運行1
B運行2
B運行3
B運行4
B運行5
B運行6
B運行7
B運行8
B運行9
Thread-1線程結束
main線程結束
現在Thread-0
、Thread-1
都加入到主線程中了,所以得等這兩個子線程結束之後才能繼續完成main
線程。那我們再來看看ts1
和ts2
線程對象都不使用join()
,會是什麼樣?下面是結果:
main線程開始
main線程結束
Thread-0線程開始
Thread-1線程開始
B運行0
A運行0
B運行1
A運行1
B運行2
A運行2
B運行3
B運行4
A運行3
B運行5
A運行4
A運行5
B運行6
A運行6
A運行7
A運行8
B運行7
A運行9
B運行8
Thread-0線程結束
B運行9
Thread-1線程結束
從結果可以看出,不加的話主線程mian
不會等Thread-0
、Thread-1
結束,會繼續運行,所以我們看到了main
線程結束的打印。