多线程中join( )方法的使用

本文详细探讨了Java中线程的join方法,通过实例展示了如何使用join使得主线程等待子线程执行完毕后再继续。join方法使得线程执行从并行变为串行,确保子线程执行完成后,主线程才开始执行。此外,还介绍了join方法的参数用法,以及在面试中如何利用join解决等待多个线程完成的问题。
摘要由CSDN通过智能技术生成

先写一个子线程

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()方法了解一下~~~

当然,答案不唯一,但很多时候我觉得面试官想听到的答案是这个,所以记得加上哦。

转载自:https://blog.csdn.net/qq_33236248/article/details/80266487

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值