Java并发工具类:CountDownLatch

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发工具类:CountDownLatch相关的知识,希望对你有一定的参考价值。

文章目录

1. CountDownLatch

之前的一些并发工具类仍然不能满足一些特定的需求,比如让某一条线程要进行整理最后数据,那么他得先等待其余线程操作数据的线程完成后在执行,如果不给上面两个工具类加锁操作是很难完成对这样复杂的数据操作编写业务的。

这就出现了CountDownLatch类 : 他可以让某一条线程等待其他线程执行完毕之后再执行

常用方法:

方法解释
public CountDownLatch(int count)参数传递线程数,表示等待线程数量,并定义了一个计数器
public void await()让线程等待,当计数器为0时,会唤醒等待的线程
public void countDown()当前线程执行完毕 ,会将计数器 -1

代码示例

有这么一个案例:妈妈等三个孩子吃完糖果然后收拾桌子
根据上面的方法,我们可以这么设计

  • 三个小朋友分别是三个吃糖果的线程

  • 然后三个线程分别传入一个CountDownLatch类对象,构造方法就要传一个对象

    public ChileThread3(CountDownLatch countDownLatch) 
        this.countDownLatch = countDownLatch;
    
    
  • 如果当前线程的孩子吃完了手里的所有糖果了,那么就调用countDown() 方法,将计数器 -1 ,那么我们重写的run方法里就可以这么写

    @Override
    public void run() 
        //1.吃糖果
        for (int i = 1; i <= 10; i++) 
            System.out.println(getName() + "在吃第" + i + "个糖果");
        
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    
    
  • 最后母亲线程就需要在运行时进行await等待,等到计数器为0时才会唤醒等待,进行收拾桌子的操作

完整代码如下:

package com.test;


import java.util.concurrent.CountDownLatch;

class ChileThread1 extends Thread 

    private CountDownLatch countDownLatch;

    public ChileThread1(CountDownLatch countDownLatch) 
        this.countDownLatch = countDownLatch;
    

    @Override
    public void run() 
        //1.吃糖果
        for (int i = 1; i <= 5; i++) 
            System.out.println(getName() + "在吃第" + i + "个糖果");
        
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    



class ChileThread2 extends Thread 

    private CountDownLatch countDownLatch;

    public ChileThread2(CountDownLatch countDownLatch) 
        this.countDownLatch = countDownLatch;
    

    @Override
    public void run() 
        //1.吃糖果
        for (int i = 1; i <= 8; i++) 
            System.out.println(getName() + "在吃第" + i + "个糖果");
        
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    



class ChileThread3 extends Thread 

    private CountDownLatch countDownLatch;

    public ChileThread3(CountDownLatch countDownLatch) 
        this.countDownLatch = countDownLatch;
    

    @Override
    public void run() 
        //1.吃糖果
        for (int i = 1; i <= 10; i++) 
            System.out.println(getName() + "在吃第" + i + "个糖果");
        
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    


class MotherThread extends Thread 
    private CountDownLatch countDownLatch;

    public MotherThread(CountDownLatch countDownLatch) 
        this.countDownLatch = countDownLatch;
    

    @Override
    public void run() 
        //1.等待
        try 
            //当计数器变成0的时候,会自动唤醒这里等待的线程。
            countDownLatch.await();
         catch (InterruptedException e) 
            e.printStackTrace();
        
        //2.收拾碗筷
        System.out.println("妈妈在收拾桌子,捡起糖果包装袋");
    


class MyCountDownLatchDemo 
    public static void main(String[] args) 
        //1.创建CountDownLatch的对象,需要传递给四个线程。
        //在底层就定义了一个计数器,此时计数器的值就是3
        CountDownLatch countDownLatch = new CountDownLatch(3);
        //2.创建四个线程对象并开启他们。
        MotherThread motherThread = new MotherThread(countDownLatch);
        motherThread.start();

        ChileThread1 t1 = new ChileThread1(countDownLatch);
        t1.setName("Lily");

        ChileThread2 t2 = new ChileThread2(countDownLatch);
        t2.setName("Lusy");

        ChileThread3 t3 = new ChileThread3(countDownLatch);
        t3.setName("LangTong");

        t1.start();
        t2.start();
        t3.start();
    


运行结果如下:

以上是关于Java并发工具类:CountDownLatch的主要内容,如果未能解决你的问题,请参考以下文章

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

Java并发工具类:CountDownLatch

『死磕Java并发编程系列』并发编程工具类之CountDownLatch

Java并发编程-CountDownLatch

Java并发编程-CountDownLatch

Java并发工具类等待多线程完成的CountDownLatch