线程加入——join()

1、join()介绍

join() 定义在Thread.java中,join() 的作用是让“父线程”等待“子线程”结束之后再继续运行,示例:

public class FatherThread extends Thread {

	public FatherThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		System.out.println("父线程开始>>>>>");
		SunThread st = new SunThread("st");
		st.start();
		try {
			st.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("父线程结束>>>>>");
	}

}

class SunThread extends Thread {
	public SunThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		System.out.println("子线程开始>>>>>");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("子线程结束>>>>>");
	}
}

//测试
public static void main(String args[]) {
	FatherThread ft = new FatherThread("ft");
	ft.start();
}

//结果
父线程开始>>>>>
子线程开始>>>>>
子线程结束>>>>>//5秒后打印
父线程结束>>>>>

在调用st.join()之后,ft父线程会一直等待,直到“子线程st”运行完毕,在“子线程st”运行完毕之后,父线程才能接着运行

2、join()方法的源码

public final void join() throws InterruptedException {
    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;
        }
    }
}

源码分析:当millis==0时,会进入while(isAlive())循环——即只要子线程是活的,主线程就不停的等待

①我们经常调用的join()实际上调用的是join(0)

②join(long millis)是一个同步方法,该方法的锁是线程对象本身,因为我们通常都是调用子线程的join(),因此此同步方法的锁是子线程对象本身(而不是父线程),在父线程中调用了子线程的join()方法之后,父线程就获取到了子线程这个对象的同步锁,我们可以看到在join(long millis)方法中调用了wait(long millis)(注意是子线程对象的wait()),这会使父线程等待——因为此时父线程持有子线程对象为锁,直到超过join规定的时间或者子线程执行结束

③如果想使父线程中同时启动多个子线程(使这几个子线程并行执行),并想确保让某个子线程先于父线程执行完成,应该在调用完所有子线程的start()后调用该子线程的join(),因为如果先调用join()会使父线程等待,而可能导致其他子线程还没有start,只能等到该join的子线程执行完之后父线程获取执行权然后再调用子线程的start启动其他子线程

④父线程中可以同时调用多个子线程的join(),这些join()方法的执行应该是顺序的,因为每调用一个子线程的join(),父线程都会wait,但这不意味着这些子线程不能并发执行,只要调用了子线程的start,那么所有start后的子线程都会并发执行,join的作用是保证该子线程先于父线程执行完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值