java并发(四)CountDownLatch闭锁

本文详细介绍了Java并发工具类CountDownLatch的使用方法及应用场景,通过实例演示如何利用CountDownLatch控制线程执行顺序,确保某些活动直到其他活动都完成才继续执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CountDownLatch

  1. Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器
    的性能。
  2. CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作
    之前,它允许一个或多个线程一直等待。
  3. 闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活
    动直到其他活动都完成才继续执行:
    • 确保某个计算在其需要的所有资源都被初始化之后才继续执行;
    • 确保某个服务在其依赖的所有其他服务都已经启动之后才启动;
    • 等待直到某个操作所有参与者都准备就绪再继续执行。

类似join和yield方法

举例说明

创建一个类实现Runnable接口在run方法中打印100以内的偶数,在主方法中测试该run方法执行时间

class LatchDemo implements Runnable{

    @Override
    public void run() {
            for(int i=0;i<100;i++){

                if(i%2==0){
                    System.out.println(i);
                }
            }    
    }
}

主函数测试方法:

    public static void main(String[] args) {
        LatchDemo ld = new LatchDemo();

        long start = System.currentTimeMillis();
        for(int i=0;i<5;i++){
            new Thread(ld).start();
        }

        long end = System.currentTimeMillis();

        System.out.println("spend time:"+(end-start));//spend time:1008
    }

输出结果:

spend time:1
0
0
0...

结果并不像我们所预想的那样,并没有计算出执行了多长时间,

原因分析

创建了10个子线程之的循环结束之后,主线程继续执行,主线程打印时间后结束,但是子线程还在运行。所以导致我们看到的结果。

解决方式

原因分析完毕,我们想在子线程全部执行完之后再继续执行主线程,这个时候打印的时间就有事子线程真正执行他的时间。

使用CountDownLatch闭锁

class LatchDemo implements Runnable{
    private CountDownLatch latch;

    public LatchDemo(CountDownLatch latch){
        this.latch = latch;
    }

    @Override
    public void run() {
        // 加上 catch 和 finally,在后这种保证方法必须被执行
        try {
            for(int i=0;i<100;i++){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(i%2==0){
                    System.out.println(i);
                }
            }
        } finally {
            latch.countDown();//相当于--,每次执行此方法就减1技计数
        }
    }
}

测试主方法:

public static void main(String[] args) {
        // 要控制 5 个线程,所以传入的是 5
        CountDownLatch latch = new CountDownLatch(5);
        LatchDemo ld = new LatchDemo(latch);
//        LatchDemo ld = new LatchDemo();

        long start = System.currentTimeMillis();
        for(int i=0;i<5;i++){
            new Thread(ld).start();
        }


        try {
            latch.await();//主线程让出cpu执行权,释放对象锁,子线程全部执行完然后继续执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();

        System.out.println("spend time:"+(end-start));//spend time:1008
    }

结果输出:

...
98
98
98
spend time:1009

可见打印输出了执行时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值