Java并发多线程编程——并发工具类CountDownLatch(线程计数器)

一、CountDownLatch的理解

  • CountDownLatch属于java.util.concurrent包下;
  • CountDownLatch类使一个线程等待其他线程各自执行完毕后再执行;
  • 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

二、CountDownLatch类中常用方法

在这里插入图片描述

  • void await() 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
  • countDown() 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。

三、CountDownLatch类代码示例

1、示例场景

 * 多个线程执行,每个线程计算文件中每行数据的总和
 * 汇总线程等待多个线程计算出结果后,在把所有结果进行汇总求和
 *      例如:线程0计算第一行数据值的和,
 *           线程1计算第二行数据值的和,
 *           线程2计算第三行数据值的和,
 *           汇总线程把线程0、线程1、线程2分别计算出的总和进行汇总求和
 *      文件指:在D盘创建test.txt文件,文件内容如下:
 *           13, 56, 123, 49, 89
 *           59,20,18,34,56,103
 *           123,342,56,78,68,84,99,28

2、代码示例

package com.xz.thread.CountDownLatch;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @description:  多个线程执行,每个线程计算文件中每行数据的总和
 *                汇总线程等待多个线程计算出结果后,在把所有结果进行汇总求和
 *                例如:线程0计算第一行数据值的和,
 *                     线程1计算第二行数据值的和,
 *                     线程2计算第三行数据值的和,
 *             在D盘创建test.txt文件,文件内容如下:
 *             13, 56, 123, 49, 89
 *             59,20,18,34,56,103
 *             123,342,56,78,68,84,99,28
 * @author: xz
 * @create: 2021-05-30 15:33
 */
public class Demo {
    //定义一个数组
    private int[] arrs;

    //构造方法,传入文件内容的行数为参数,有几行数据就声明多大的数组
    public Demo(int line){
        arrs =new int[line];
    }

    /**
     * 计算方法(每行数据的值求和)
     */
    public void calculate(String line,int index,CountDownLatch latch){
        //用逗号切分每一个值
        String[] split = line.split(",");
        //遍历求每行的数据总和
        int sum=0;
        for(String str:split){
            sum += Integer.parseInt(str);
        }
        //每行的数据总和赋值到声明的arrs数组中指定位置
        arrs[index] = sum;
        System.out.println(Thread.currentThread().getName()+" 执行计算任务-------"+line+" 结果="+sum);
        latch.countDown();//递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
    }

    /**
     * 每行数据的和相加,求出总和
     */
    public void totalSum(){
        System.out.println("汇总线程【开始执行】========");
        int total=0;
        for(int i=0;i<arrs.length;i++){
            total += arrs[i];
        }
        System.out.println("汇总线程【执行完毕】========,最终结果="+total);
    }

    /**
     * 读取文件内容方法
     * @return
     */
    private static List<String> readFiles(){
        List<String> contents =new ArrayList<>();
        String line = null;
        BufferedReader br =null;
        try {
            br=new BufferedReader(new FileReader("D://test.txt"));
            while((line = br.readLine()) !=null){
                contents.add(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(br !=null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return contents;
    }
    
	//主方法,测试用
    public static void main(String[] args) {
        //读取文件内容
        List<String> contents =readFiles();
        //获取文件内容的行数
        int lineCount=contents.size();
        //实例化CountDownLatch,并传入内容的行数
        CountDownLatch latch =new CountDownLatch(lineCount);

        Demo d =new Demo(lineCount);

        //有几行就创建几个线程
        for(int i=0;i<lineCount;i++){
            final int j=i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    d.calculate(contents.get(j),j,latch);
                }
            }).start();
        }
        //使当前线程在锁存器倒计数至零之前一直等待
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        d.totalSum();
    }
}

2、运行main函数,输出结果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小志的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值