java多线程中CountDownLatch的介绍

今天在看使用zookeeper实现简单分布式锁的文章中看到了CountDownLatch这个类,但是以前没有用过就自己学习了下。

CountDownLatch类是一个同步工具类,它允许一个或者多个线程一直等待直到其他线程执行完成之后然后再执行。

其中countDown()方法是当一个被等待的执行线程数执行完成了之后减1,await()是让调用函数被阻塞,直到被等待的线程执行完成countDown()减为0的时候等待的线程才会从阻塞状态变为运行状态。

下面设计一个简单的例子:

  • 1.创建一个抽象的base线程类BaseThread
package com.lijie.thread;

import java.util.concurrent.CountDownLatch;

public abstract class BaseThread implements Runnable{

    protected CountDownLatch cdl;

    protected String serverName;

    protected long time;

    /**
     * 构造函数
     * @param cdl
     * @param serverName
     */
    public BaseThread(CountDownLatch cdl, String serverName,long time) {
        super();
        this.cdl = cdl;
        this.serverName = serverName;
        this.time = time;
    }

    @Override
    public void run() {
        callBack();
    }

    /**
     * 回调函数
     */
    public abstract void callBack();

}
  • 2.创建一个WorkThread继承上面的BaseThread,并且实现callBack()函数

注意:cdl.countDown()方法最好是放在finally块里面,防止有异常程序中断,CountDownLatch的计数一直不为0,导致后面的线程无法执行,或者等待超时。

package com.lijie.thread;

import java.util.concurrent.CountDownLatch;

public class WorkThread extends BaseThread{

    public WorkThread(CountDownLatch cdl, String serverName, long time) {
        super(cdl, serverName, time);
    }

    @Override
    public void callBack() {
        try {
            System.out.println("开始"+serverName);
            Thread.sleep(time);
            System.out.println("完成"+serverName);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            cdl.countDown();
        }
    }

}
  • 3.创建主函数
package com.lijie.thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainClass {

    private static CountDownLatch cdl;

    public static void main(String[] args) throws InterruptedException {

        cdl = new CountDownLatch(3);

        BaseThread b1 = new WorkThread(cdl,"吃饭",7000);
        BaseThread b2 = new WorkThread(cdl,"睡觉",3000);
        BaseThread b3 = new WorkThread(cdl,"打豆豆",5000);

        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.execute(b1);
        executor.execute(b2);
        executor.execute(b3);

        cdl.await();

        System.out.println("开始主函数!");
        executor.shutdown();

    }
}
  • 4.执行主函数,并查看结果
    这里写图片描述

  • 5.为什么使用抽象类

这里使用抽象类,主要是为了定义一个callBack()的动作规范,多个类去继承base类的时候都需要实现里面的callBack()方法,这样就能规范子类的一些必须定义的行为,而且子类又可以自己定义这些行为,这样设计类的层级结构、扩展性都很好。

Java CountDownLatch 是一种同步工具,它可以用来控制线程的执行顺序或者等待其他线程完成某些操作。下面是一个使用 CountDownLatch 的示例,用于实现多线程的协调: ```java import java.util.concurrent.CountDownLatch; public class MultiThreadExample { public static void main(String[] args) throws InterruptedException { int threadCount = 5; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { Thread thread = new Thread(new Worker(latch)); thread.start(); } System.out.println("Main thread is waiting for workers to finish."); latch.await(); System.out.println("All workers have finished. Main thread can continue."); } static class Worker implements Runnable { private final CountDownLatch latch; public Worker(CountDownLatch latch) { this.latch = latch; } @Override public void run() { try { System.out.println("Worker is performing some task."); Thread.sleep(1000); System.out.println("Worker has finished its task."); } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); } } } } ``` 在上面的示例,我们创建了一个 CountDownLatch 对象,并将其初始化为预期的线程数量(5)。然后,在主线程创建了 5 个 Worker 线程,并启动它们。每个 Worker 线程都会执行一些任务,然后调用 `latch.countDown()` 来通知 CountDownLatch 已经完成了一部分工作。最后,主线程调用 `latch.await()` 来等待所有 Worker 线程完成任务。 当所有 Worker 线程完成任务后,主线程就会继续执行。这样,我们就通过 CountDownLatch 来协调多线程的执行顺序了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值