关于CountDownLatch个人理解

关于CountDownLatch的个人理解:

1.CountDownLatch是一个同步工具类,用来控制一个或多个线程等待,直到其他线程执行完毕后再执行。

2.CountDownLatch维护了一个计数器cnt,计数器的初始值为线程总数,每当执行 countDown()方法时计数器的值都会减1,当计数器减到0时代表所有的线程执行完毕,然后那些因为调用await()方法而处于等待状态的线程就会被唤醒。
关于CountDownLatch个人理解_第1张图片

3.CountDownLatch主要的两个方法countDown()方法和await()方法,countDown()方法用于使计数器减一,其一般是执行任务的线程调用,await()方法则使调用该方法的线程处于等待状态,其一般是主线程调用。这里需要注意的是,countDown()方法并没有规定一个线程只能调用一次,当同一个线程调用多次countDown()方法时,每次都会使计数器减一;另外,await()方法也并没有规定只能有一个线程执行该方法,如果多个线程同时执行await()方法,那么这几个线程都将处于等待状态,并且以共享模式享有同一个锁。(转载自简书,作者:爱宝贝丶,链接https://www.jianshu.com/p/128476015902)
对于我个人的理解来说,调用countDown()方法用于代表当前线程执行完毕,计数器减一;调用await()方法代表当前线程暂告一段落,等待计数器内的线程执行完毕后,该线程才会继续执行。

4.代码示例

//1000个线程对cnt进行加1操作
public class fourtext {
 private int cnt = 0;
 // 添加锁,否则多个线程操作同时操作可能出错
 //此代码并不完美,多次运行仍可能出现错误结果,只是一个验证的思路
 public synchronized void add() {
  cnt++;
 }
 public int get() {
  return cnt;
 }
 public static void main(String[] args) throws InterruptedException {
  fourtext example = new fourtext();
  final CountDownLatch countDownLatch = new CountDownLatch(998);
  ExecutorService executorService = Executors.newCachedThreadPool();
  for (int i = 0; i < 2; i++) {
   executorService.execute(() -> {
    try {
     countDownLatch.await();// 阻塞当前运行线程
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    example.add();
    countDownLatch.countDown();// 代表该线程执行完毕
   });
  }
  // 因第一个for循环的两个线程调用了await()所以此时的cnt值为0
  System.out.println(example.get());
  for (int i = 0; i < 998; i++) {
   executorService.execute(() -> {
    example.add();
    countDownLatch.countDown();// 代表该线程执行完毕
   });
  }
  executorService.shutdown();// 当所有线程都执行完毕则关闭ExecutorService对象
  // 此时的值为1000,因为第二个for循环执行完毕,CountDownLatch维护的计数器值减到0,从而唤醒之前第一个for循环的两个线程
  System.out.println(example.get());
 }
}

你可能感兴趣的:(java基础知识个人见解)