引言:更多线程的认识可以看一篇博客:
一、join()的作用
我们知道线程是随机调度执行的,但是有时候我们需要另一个任务完成了,我们才能继续,这个时候我们就可以使用join去等待线程结束。
例如:别人向我转100万,需要转完了我再看是否接收到了100万。
二、代码举例
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
for (int i = 0; i < 3; i++) {
System.out.println("我正在向作者赚钱");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("作者准备接收钱");
//创建t线程,并调用run方法
t.start();
//main线程等待t线程结束
t.join();
System.out.println("作者收到了,等待结束");
}
结果:
谁调用join谁就等,在主线程中调用 t.join() ,就是main线程等待 “t” 线程结束。
三、join() 抛出的异常
除了join,sleep也会抛出这样的一个异常:
如果是run方法中使用,不能使用throws向上抛,因为Thread类中没有处理这个异常,我们只能使用try catch处理掉这个异常。
如果是在主方法中我们可以通过throws抛给JVM来处理这个异常,或者try catch 也是可以的:
四、join()的重载
方法 | 说明 |
public void join() | 死等线程结束 |
public void join(long millis) | 等待线程结束,最多millis毫秒 |
public void join(long millis , int nanos) | 同理,但可以更高精度(纳秒级别) |
第三种了解就可以了,普通的计算机很难精确到纳秒,精确到毫秒就不错了。
这里着重讲一下第三种,只要时间到就继续执行,不会等到 t 线程结束。
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
//大概5秒
for (int i = 0; i < 5; i++) {
System.out.println("hello Thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
System.out.println("main开始等待");
//大概3秒
t.join(3000);
System.out.println("main等待结束");
}
任意线程都可以进行等待,不是只有主线程可以去等待别的线程。
五、多个线程的等待
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
//大概5秒
for (int i = 0; i < 5; i++) {
System.out.println("hello t1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
//大概5秒
for (int i = 0; i < 5; i++) {
System.out.println("hello t2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
System.out.println("main开始等待");
//大概3秒
t1.join();
t2.join();
System.out.println("main等待结束");
}
这样写可以保证线程之间的执行关系:
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
//大概5秒
for (int i = 0; i < 3; i++) {
System.out.println("hello t1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
//大概5秒
for (int i = 0; i < 3; i++) {
System.out.println("hello t2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t1.join();
t2.start();
t2.join();
}