多线程join方法的理解

join方法是定义在Thread类里的一个final成员方法,因此需要一个Thread对象调用该方法,其语义为将调用join方法的线程对象加入到当前执行线程中先去执行。

先上源码

    /**
     * Waits for this thread to die.(等待直到调用该方法的线程死亡,即线程运行结束)
     * ......(省略)
     */
    public final void join() throws InterruptedException {
        join(0);
    }
    /**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     * 当超时时间为0时意味着永远等待
     * ......(省略)
     */
    public final synchronized void join(long millis)
    throws InterruptedException {
        ...(省略)
        if (millis == 0) {
        	//主要逻辑部分(注意该方法是synchronized修饰的此时已经获取了调用该方法线程对象的锁)
        	//当this.isAlive()即当前调用join方法的线程是运行状态即调用了start方法
        	//那么调用this.wait(0);(即调用join方法的线程)
        	//会释放锁资源并在调用join方法的当前线程中等待
        	//此时释放锁资源之后
            while (isAlive()) {
                wait(0);
            }
        } else {
           ...
        }
    }

测试代码分析

    public class JoinTest {
    static Integer j = 0;
    public static void main(String[] args) throws Exception {
        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                j ++;
                try {
                    Thread.sleep(200);
                } catch (Exception e){

                }
                String name = Thread.currentThread().getName();
                System.out.println(name + " : " + j);
            }
        },"t1");
        Thread t2 = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                j ++;
                try {
                    Thread.sleep(300);
                } catch (Exception e){
                }
                if (i > 0){
                    try {
                        t.join();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                String name = Thread.currentThread().getName();
                System.out.println(name + " : " + j);
            }
        },"t2");
        t.start();

        t2.start();
        Thread.sleep(1);
        System.out.println(j);
    }
}

顺序执行,当t.start()在sleep(200)处暂停,t2.start()在sleep(300)处暂停,最后一行打印2,
t中暂停时间先到打印"t1 : 2",再次循环并暂停,然后t2暂停时间到打印"t2 : 3 " 再次循环暂停在
sleep(300),t1再次打印,同时循环,t2暂停时间到,调用t.join()获取t的锁之后调用wait()方法
释放锁
并在此处等待直到t1线程执行完成唤醒此处的wait
注:最终t1执行完的唤醒是notifyAll唤醒所有等待t1的线程,此处的wait只对t2起作用(即只是在当前线程中等待),对主线程或其他未调用t.join()的线程不会阻塞等待。且join只在线程运行过程中有效,当线程运行完,join的调用并未起到任何作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值