join

join代码演示

import java.util.ArrayList;
import java.util.List;

public class JoinTest {
    public static void main(String[] args) {
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            threads.add(new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " running...");
            }, "" + i));
        }

        threads.forEach(t -> {
            t.start();
            try {
                // 主线程等待所有的t运行完毕后才会执行,循环也会卡在t.join处,等到join结束才会继续下一次循环
                t.join();
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
        });

        System.out.println("run over!");
    }
}

 正如注释所写,主线程会等待另外50个子线程运行完毕之后才会运行,而每一个子线程也会等待上一个子线程运行完毕之后才会运行。这是因为:

join()方法调用的是join(millis)方法, join(millis)方法加了同步关键字,主线程会持有对象t的锁,然后
(1)若join(millis)方法的参数是0,则主线程会无限等待下去,直到子线程退出时将其唤醒。主线程循环判断t的isAlive方法的返回值是否为true(t在start之后、消亡之前都是true),若为true则调用wait(0)一直等待下去,直到线程消亡时调用notifyAll方法通知主线程。若中间被意外唤醒,由于isAlive方法是true,因此还会继续阻塞
(2)若join(millis)方法的参数大于0,主线程也会循环判断t的isAlive方法的返回值是否为true,是true则调用wait(millis)等待一段时间,等到这段时间之后就会退出等待,或者线程消亡时通过notifyAll方法唤醒wait方法,这时isAlive会返回false,然后退出。若中间被意外唤醒,由于isAlive方法是true,因此还会继续阻塞,并会重新计算阻塞的时间

join必须在start之后调用,否则t的isAlive方法会返回flase,主线程不会阻塞

 

join(millis)方法源码

public final synchronized void join(long millis) throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0L;
        if (millis < 0L) {
            throw new IllegalArgumentException("timeout value is negative");
        } else {
            if (millis == 0L) {
                while(this.isAlive()) {
                    this.wait(0L);
                }
            } else {
                while(this.isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0L) {
                        break;
                    }

                    this.wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }

        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值