join方法为Thread类的接口方法,它有两种重载方式,传空参和传毫秒数(long millis)。这个方式表示等待这个线程死亡(最多millis秒)。举个最简单的例子:
public class Main {
public static void main(String[] args) {
Thread myThread1 = new Thread(new MyThread(), "子线程1");
myThread1.start();
for (int i = 0; i < 10; i++) {
System.out.println("main线程:" + i);
}
}
}
class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
按照之前的多线程知识,main线程和sub线程将交叉打印i的值:
这时有个需求,main线程等sub线程执行完后再执行,那么就在main线程中调用sub线程对象的join方法并捕获异常。将main方法改为:
public static void main(String[] args) {
Thread myThread1 = new Thread(new MyThread(), "子线程1");
myThread1.start();
try {
myThread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("main线程:" + i);
}
}
运行结果:
原因:在sub线程启动后,main线程中sub线程对象调用join方法,此时main线程就一直等着sub线程执行完死亡才执行自己的逻辑。这样做又让程序的执行方式变为之前一条路径执行。
现在有一个新需求,有T1,T2,T3三个线程,让T1先执行完再执行T2,T2执行完再执行T3,那么代码可能是这样:
public class Main {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("T1:" + i);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("T2:" + i);
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("T3:" + i);
}
}
});
t1.start();
t2.start();
t3.start();
}
}
如果main线程中还有逻辑代码,那么main线程中还要调用t3.join()。运行结果和单线程运行的一样...纯属没事找事!
//下面看一个比较简单的多线程应用案例