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

Posted 小志的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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函数,输出结果如下:

在这里插入图片描述

以上是关于Java并发多线程编程——并发工具类CountDownLatch(线程计数器)的主要内容,如果未能解决你的问题,请参考以下文章

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

Java并发多线程编程——并发工具类CyclicBarrier(回环栅栏)

Java并发多线程编程——并发工具类Semaphore(信号量)

Java多线程系列:CountDownLatchSemaphore等4大并发工具类详解

Java多线程系列:CountDownLatchSemaphore等4大并发工具类详解

最全Java并发编程技能:多线程+线程池+线程锁+并发工具+并发容器