Java執行緒的Thread.join()
方法可以讓目前正在執行的執行緒暫停,直到呼叫join()
的執行緒執行結束才會繼續執行。
例如下面範例,在Thread-b進入run()
後便呼叫Thread-a物件的join()
,因此Thread-b會暫停執行,直到Thread-a執行結束為止。
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-a");
Thread b = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
try {
a.join(); // Thread-b暫停直到Thread-a執行結束才會繼續執行
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-b");
a.start();
b.start();
}
}
執行結果
Thread-a:start
Thread-b:start
Thread-a:0
Thread-a:1
Thread-a:2
Thread-a:3
Thread-a:4
Thread-a:end
Thread-b:0
Thread-b:1
Thread-b:2
Thread-b:3
Thread-b:4
Thread-b:end
執行順序圖:
要注意的是,被暫停的只有那條正在執行並呼叫另一條執行緒物件的join()
的執行緒而已,其他執行緒不受影響。例如上面範例等待Thread-a執行結束的只有Thread-b而已。
承上,再多加另一條執行緒Thread-c來執行。
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-a");
Thread b = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
try {
a.join(); // Thread-b暫停直到Thread-a執行結束才會繼續執行
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-b");
Thread c = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-c");
a.start();
b.start();
c.start();
}
}
從下面的執行結果可以看到Thread-b在等到Thread-a執行結束才會繼續執行,但Thread-c不受影響。
Thread-a:start
Thread-b:start // <--接著呼叫a.join(),Thread-b暫停
Thread-a:0
Thread-a:1
Thread-c:start
Thread-a:2
Thread-c:0
Thread-a:3
Thread-c:1
Thread-a:4
Thread-c:2
Thread-a:end // <--Thread-a執行結束
Thread-c:3
Thread-c:4
Thread-c:end
Thread-b:0
Thread-b:1
Thread-b:2
Thread-b:3
Thread-b:4
Thread-b:end
如果將第一個範例的a.join()
改在main()
中呼叫如下,會發現Thread-b不會暫停了,因為暫停執行的是main執行緒。
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-a");
Thread b = new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + ":start");
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println(Thread.currentThread().getName() + ":end");
}
}, "Thread-b");
a.start();
b.start();
try {
a.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread.join()
會拋出InterruptedException
例外,必須用try-catch捕捉。
join()
只有在執行緒存活時才有作用。
沒有留言:
張貼留言