你好,多线程join()方法了解一下~~
先写一个子线程
public class MyThread extends Thread{
public MyThread(String name){
super(name);
}
@Override
public void run(){
for(int i=0;i<=20;i++){
System.out.println(this.getName() + ":" + i);
}
}
}
再写主线程测试类
public class TestThread {
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread("子线程");
mt.start();
for (int i = 0; i <= 20; i++) {
System.out.println("主线程:" + i);
}
}
}
执行main方法,打印结果很明显,主线程和子线程会交替打印
主线程:0
子线程:0
主线程:1
子线程:1
主线程:2
子线程:2
主线程:3
主线程:4
子线程:3
主线程:5
子线程:4
子线程:5
子线程:6
子线程:7
子线程:8
子线程:9
子线程:10
子线程:11
子线程:12
子线程:13
主线程:6
主线程:7
......
然后,我们在主线程打印之前,加一句mt.join(),会怎样呢?
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread("子线程");
mt.start();
mt.join();
for (int i = 0; i <= 20; i++) {
System.out.println("主线程:" + i);
}
}
执行main方法,打印结果如下:
子线程:0
子线程:1
子线程:2
子线程:3
子线程:4
子线程:5
子线程:6
子线程:7
子线程:8
子线程:9
子线程:10
子线程:11
子线程:12
子线程:13
子线程:14
子线程:15
子线程:16
子线程:17
子线程:18
子线程:19
子线程:20
主线程:0
主线程:1
主线程:2
主线程:3
主线程:4
主线程:5
主线程:6
主线程:7
主线程:8
主线程:9
主线程:10
主线程:11
主线程:12
主线程:13
主线程:14
主线程:15
主线程:16
主线程:17
主线程:18
主线程:19
主线程:20
没错,一目了然,子线程全部执行完了之后,主线程才开始执行了,所以我们可以大胆猜想,join方法会让子线程优先执行完再去执行主线程?
这时候,我们来看一下join()方法的源码,验证一下我们的猜想是否正确:
public final void join() throws InterruptedException {
join(0);
}
其中join(0)的具体源码如下:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
从源码我们可以看出,join是一个同步的方法,主线程调用了子线程的join()方法,相当于调用了子线程的wait()方法,当子线程执行完,或者达到等待时间的时候,主线程才会继续执行。
结论:原来主线程和子线程是并行的关系,但是一旦使用了join()方法,就会变成串行的关系;当主线程调用子线程的join()方法时,意味着必须等子线程执行完毕之后,主线程才会开始执行。
另外,join()方法也可以传参long类型的时间,比如
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread("子线程");
mt.start();
mt.join(1L);
for (int i = 0; i <= 20; i++) {
System.out.println("主线程:" + i);
}
}
join(1L)意味着子线程执行1毫秒后,主线程恢复执行;
所以打印结果如下:
子线程:0
子线程:1
子线程:2
子线程:3
子线程:4
子线程:5
子线程:6
子线程:7
子线程:8
子线程:9
主线程:0
子线程:10
主线程:1
子线程:11
主线程:2
子线程:12
主线程:3
子线程:13
主线程:4
子线程:14
主线程:5
子线程:15
主线程:6
子线程:16
主线程:7
子线程:17
主线程:8
子线程:18
主线程:9
子线程:19
主线程:10
子线程:20
主线程:11
主线程:12
主线程:13
主线程:14
主线程:15
主线程:16
主线程:17
主线程:18
主线程:19
主线程:20
引申:
面试题:有一个主线程,里面有三个子线程,想等三个子线程都执行完毕后,才执行主线程,怎么办?
答案(之一):join()方法了解一下~~~
当然,答案不唯一,但很多时候我觉得面试官想听到的答案是这个,所以记得加上哦。