Loading...
墨滴

Bayanbulake

2022/01/09  阅读:29  主题:自定义主题1

Java多线程通信方式[四]

使用CountDownLatch实现多线程闭锁

CountDownLatch是一个同步工具类,可以用来协调多个线程的执行时间。

例如:可以让A线程在其他线程运行完毕之后再执行。也就是说,如果其他线程没有执行完毕,则A线程就会一直等待。这种特性也称之为闭锁

闭锁的使用场景:

  • 确保某个计算,在其需要的所有资源都准备就绪后再执行。
  • 确保某个服务,在其依赖的所有服务都已启动后再启动。
  • 确保某个任务,在所有参与者都准备就绪后再执行。

CountDownLatch的原理

CountDownLatch在创建时,会指定一个计数器,表示等待的执行线程数量。然后每个线程在执行完毕之后,分别调用一次countDown()方法,用来递减计数器,表示一个线程数执行完了。此时线程A可以调用await()方法,使当前线程一直阻塞,直到计数器为0,线程A才会执行。如果线程A一直无法等到计数器为0,则会显示等待超时,也可以在线程A等待时,通过程序中断。

学习CountDownlatch的代码如下:

package com.geovis.bin.custom.study.wangbin;

import java.util.concurrent.CountDownLatch;

/**
 * @Author: Wangb
 * @EMail: 1149984363@qq.com
 * @Date: 25/12/2021 上午10:32
 * @Description
 */

public class TestCountDownLatch {
    public static void main(String[] args) {
        //计数器为10
        CountDownLatch countDownLatch = new CountDownLatch(10);

        /**
         * 将CountDownLatch对象传递到线程的run()方法中,当每个线程执行完毕run()后就将计数器减1
         */

        MyThread myThread = new MyThread(countDownLatch);
        long start = System.currentTimeMillis();
        //创建10个线程,并执行
        for (int i = 0; i < 10; i++) {
            new Thread(myThread).start();
        }
        try {
            /**
             * 主线程(main)等待:等待的计数器为0;即当CountDownLatch中的计数器为0时,Main线程才会继续执行。
             */

            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start));
    }
}
class MyThread implements Runnable {
    private CountDownLatch latch;
    public MyThread(CountDownLatch latch) {
        this.latch = latch;
    }
    @Override
    public void run() {
        try {
            Thread.sleep(3000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        finally {
            latch.countDown();//每个子线程执行完毕后,触发一次countDown(),即计数器减1
        }
    }
}

代码流程分析:

  • 在开始记录执行时间start;
  • 在执行时创建了10个子线程,并通过CountDownLatchawait()方法等待子线程执行完毕。
  • 当子线程全部执行完毕后,Main线程结束了await()等待,继续向下执行,然后记录结束的时间end;
  • 最后计算end-start执行时间;

程序运行结果如下图所示:

以上就是关于CountDownLatch在多线程通信中的案例学习,希望对你有所帮助~

Bayanbulake

2022/01/09  阅读:29  主题:自定义主题1

作者介绍

Bayanbulake