并发编程:CountDownLatch

1. CountDownLatch

  • 倒计时锁;某个线程x当倒计时为0的时候才执行;倒计时其实就是一个int类型的变量,在初始化CountDownLatch的时候会给他一个初始值;在多线程工作的时候,使用await()阻塞线程,通过countDown()方法来对计数器-1;当等于0的时候线程则会解除阻塞运行。

基本语法

//初始化对象,给一个初始值
CountDownLatch latch = new CountDownLatch(3);
//x线程 调用await阻塞 等待计数器为0的时候才会解除阻塞
latch.await();
//其他线程调用countDown();对计数器-1
latch.countDown();

2. 代码示例

2.1 单机版

package org.example.CountDownLatch;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Slf4j
public class CountDownLatchTest {

    static int count = 3;

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(count);
        for (int i = 0; i < count; i++) {
            int time = i;
            new Thread(() -> {
                log.info("{} start...",Thread.currentThread().getName());
                try {
                    TimeUnit.SECONDS.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                latch.countDown();
                log.info("{} end...,count[{}]", Thread.currentThread().getName(), latch.getCount());
            }, "t" + i).start();
        }
        log.info("main await start");
        latch.await();
        log.info("main await end");
    }

}

在这里插入图片描述

2.2 配合线程池ExecutorService

package org.example.CountDownLatch;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class CountDownLatchTest2 {

    public static void main(String[] args){
        AtomicInteger result1 = new AtomicInteger();
        AtomicInteger result2 = new AtomicInteger();
        AtomicInteger result3 = new AtomicInteger();
        AtomicInteger finalResult = new AtomicInteger();
        //线程池里面创建4个线程,其中前3个用于计算,第四个用于汇总前3个线程的计算结果
        AtomicInteger i= new AtomicInteger();
        ExecutorService executorService = Executors.newFixedThreadPool(4,
                (fisher)-> new Thread(fisher,"t"+i.incrementAndGet()));
        //前3个线程先执行
        CountDownLatch latch = new CountDownLatch(3);

        executorService.submit(()->{
            log.debug("t1 thread start");
            try {
                TimeUnit.SECONDS.sleep(1);
                result1.set(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            log.debug("t1 thread end;count[{}]", latch.getCount());
        });

        executorService.submit(()->{
            log.debug("t2 thread start");
            try {
                TimeUnit.SECONDS.sleep(2);
                result2.set(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            log.debug("t2 thread end;count[{}]", latch.getCount());
        });

        executorService.submit(()->{
            log.debug("t3 thread start");
            try {
                TimeUnit.SECONDS.sleep(3);
                result3.set(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            log.debug("t3 thread end;count[{}]", latch.getCount());
        });

        //汇总计算结果
        executorService.submit(()->{
            log.debug("t4 watiing");
            try {
                latch.await();
                finalResult.set(result1.get() + result2.get() + result3.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("t4 wait end...");
            log.debug("finalResult=" + finalResult);
        });
        executorService.shutdown();
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值