JUC

CountDownLatch


countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

countDownLatch类中只提供了一个构造器:

//参数count为计数值
public CountDownLatch(int count) {  };
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };   
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
//将count值减1
public void countDown() { };  

演示:教师有6个同学和班长,班长需要等6个同学都走后才能锁门。

import java.util.concurrent.CountDownLatch;

public class CountdownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch=new CountDownLatch(6);//6个线程
        for (int i=0;i<6;i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+ "学生离开教室");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.await();//6线程个执行完才执行下面
        System.out.println("班长锁门!");

    }
}
0学生离开教室
1学生离开教室
3学生离开教室
4学生离开教室
2学生离开教室
5学生离开教室
班长锁门!

场景说明:

  • 模拟多线程分组计算
  • 有一个大小为50000的随机数组,用5个线程分别计算10000个元素的和
  • 然后在将计算结果进行合并,得出最后的结果。
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class CountdownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        //数组大小
        int size = 50000;
        //定义数组
        int[] numbers = new int[size];
        //随机初始化数组
        Random random = new Random();
        for (int i = 0; i < size; i++) {
            numbers[i] = random.nextInt(100);
        }

        //单线程计算结果
        System.out.println();
        Long sum = 0L;
        for (int i = 0; i < size; i++) {
            sum += numbers[i];
        }
        System.out.println("单线程计算结果:" + sum);
//----------------------------------------------------------------------------------------------------------------------
        //定义五个Future去保存子数组计算结果
        final int[] results = new int[5];
        //子数组长度
        int length = 10000;
        CountDownLatch countDownLatch=new CountDownLatch(5);//5个线程
        for (int i=0;i<5;i++){
            int finalI = i;
            int[] subNumbers = Arrays.copyOfRange(numbers, (i * length), ((i + 1) * length)); //每个线程计算一份数组
            new Thread(()->{
                for (int j = 0; j <subNumbers.length ; j++) {
                    results[finalI]+=subNumbers[j];
                }
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.await();//5个线程个执行完才执行下面
        int sums = 0;
        for (int i = 0; i < 5; i++) {
            sums += results[i];
        }
        System.out.println("多线程计算结果:" + sums);

    }
}
单线程计算结果:2483567
多线程计算结果:2483567
  • 作者:低调做个路人 (扫码联系作者)
  • 发表时间:2019-11-26 14:00:00
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 评论

    测试人员
    谁啊
    测试人员   @测试人员
    努伊斯
    测试人员   @测试人员
    厉害