join方法介绍
join方法是Thread类的方法,不是Object对象的方法,是无参的且返回值为void的方法。
等待子线程执行完成,再继续执行主线程
来看一个示范:
package com.tim.base.easystart.thread.base;
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
System.out.println("main thread start");
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("child thread: threadA is over");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("child thread: threadB is over");
}
});
threadA.start();
threadB.start();
System.out.println("threadA and threadB has been started");
//等待threadA和threadB执行完毕返回
threadA.join();
threadB.join();
System.out.println("all child thread over!");
}
}
输出结果:
main thread start
threadA and threadB has been started
child thread: threadA is over
child thread: threadB is over
all child thread over!
可以看出2个子线程threadA和threadB启动之后,main线程继续执行,等执行完join方法之后,main线程暂停执行,等待2个线程执行完成,才继续执行join方法之后的程序代码。
线程中断与join方法
public class JoinInterruptTest {
public static void main(String[] args) {
System.out.println("main thread start");
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("child thread: threadA begin");
for (;;) {
try {
Thread.sleep(500);
System.out.println("child thread:threadA is executing");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread mainThread = Thread.currentThread();
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("child thread: threadB begin");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("child thread: threadB will interrupt mainThread");
mainThread.interrupt();
}
});
threadA.start();
threadB.start();
try {
threadA.join();
}
catch (InterruptedException e) {
System.out.println("main thread:" + e);
}
}
}
输出结果:
main thread start
child thread: threadA begin
child thread: threadB begin
child thread:threadA is executing
child thread:threadA is executing
child thread: threadB will interrupt mainThread
main thread:java.lang.InterruptedException
child thread:threadA is executing
child thread:threadA is executing
…
child thread:threadA is executing
child thread:threadA is executing
threadB执行过程中调用了主线程mainThread的interrupt方法,为主线程设置了中断标志,这时在threadA.join等待threadA返回的try{}catch{}代码块中会捕获到InterruptedException,但是threadA并没有被中断,还是继续执行。
一直执行的线程休眠中被中断的不会导致线程退出
还发现一个有趣的现象:在上面的代码中将mainThread.interrupt();换成threadA.interrupt();
package com.tim.base.easystart.thread.base;
public class JoinInterruptTest {
public static void main(String[] args) {
System.out.println("main thread start");
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("child thread: threadA begin");
for (;;) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
System.out.println("threadA is interrupted..." + e);
}
System.out.println("threadA is still executing...");
}
}
});
Thread mainThread = Thread.currentThread();
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("child thread: threadB begin");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("child thread: threadB will interrupt mainThread");
threadA.interrupt();
}
});
threadA.start();
threadB.start();
try {
threadA.join();
}
catch (InterruptedException e) {
System.out.println("main thread:" + e);
}
}
}
输出结果:
main thread start
child thread: threadA begin
child thread: threadB begin
threadA is still executing…
child thread: threadB will interrupt mainThread
threadA is interrupted…java.lang.InterruptedException: sleep interrupted
threadA is still executing…
threadA is still executing…
…
threadA is still executing…
threadA is still executing…
可以看出threadA在sleep的时候被设置中断标志后,线程并没有停止运行,还是在继续执行。