Thread.join()与countDownLatch

本文对比分析了Java中join方法和CountDownLatch在多线程同步中的应用,详细讲解了它们的工作原理及具体实现方式,通过代码示例展示了如何使用这两种方法来确保线程间的正确执行顺序。

前言

countDownLatch允许一个或者多个线程等待其他线程完成操作后才能够执行,那么join方法也可以实现这种效果,代码如下,主线程等其他线程执行完以后才能够执行,也就是每次在其他线程在主线程中调用join方法时,main方法所在线程会阻塞进行等待,只有等调用join的线程执行完成,主线程才会执行,join的具体详解可以参考Java多线程join方法实例分析

Join实现

public class JoinTest {
    static int threadNum = 2;
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < threadNum; i++) {
            Thread thread=new Thread(new _Thread(i + 1));
            thread.start();
            thread.join();
        }
//        只有等线程1和线程2执行完成后主线程才能执行
        System.out.println("线程执行完成的时间为"+System.currentTimeMillis());
    }
}
class _Thread implements Runnable {
    private int id;
    public _Thread(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        System.out.println("线程"+id+"执行的时间为"+ System.currentTimeMillis());
    }
}
运行结果:
线程1执行的时间为1557717528311
线程2执行的时间为1557717528312
线程执行完成的时间为1557717528312

这里对输出结果的顺序做一下解释,由于主线程先开启了线程1,接着阻塞,等线程1结束后才会开启了线程2,所以输出结果顺序总是线程1先输出,接着线程2,再接着主线程。

那么countDownLatch是怎么实现的呢?其实原理上大致是一致的,countDownLatch的构造函数会初始化一个计数器N,线程每调用一次countDown方法,计数器便会减一,可以是N个线程每个都减一,也可以是一个线程调用N个countDown方法,在计数器为0时,调用await方法就不会阻塞当前线程,也就是下面的例子主线程最后执行。注意,如果不在主函数中调用await方法,主线程不会阻塞。

 countDownLatch

public class CountDownLatchTest {

    static int threadNum = 2;
    static CountDownLatch countDownLatch= new CountDownLatch(threadNum);
    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < threadNum; i++) {
            new Thread(new MyThread(countDownLatch,i+1)).start();
        }
        countDownLatch.await();
        System.out.println("线程执行完成的时间为"+System.currentTimeMillis());
    }
}

class MyThread implements Runnable {
    private CountDownLatch c;
    private int id;
    MyThread(CountDownLatch c,int id){
        this.c = c;
        this.id = id;
    }
    
    @Override
    public void run() {
        System.out.println("线程"+id+"执行的时间为"+ System.currentTimeMillis());
        c.countDown();
    }
}
运行结果:
线程1执行的时间为1557717738636
线程2执行的时间为1557717738642
线程执行完成的时间为1557717738643

这里线程1和线程2的输出结果顺序不能作保证,两个线程都有可能先执行,顺序有CPU的调度所决定。 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值