解读java同步类CountDownLatch

同步辅助类:

    CountDownLatch是一个同步辅助类,在jdk5中引入,它允许一个或多个线程等待其他线程操作完成之后才执行。    

实现原理 :

    CountDownLatch是通过计数器的方式来实现,计数器的初始值为线程的数量。每当一个线程完成了自己的任务之后,就会对计数器减1,当计数器的值为0时,表示所有线程完成了任务,此时等待在闭锁上的线程才继续执行,从而达到等待其他线程完成任务之后才继续执行的目的。

 

CountDownLatch主要方法:

    CountDownLatch具体是通过同步器来实现的,使用AQS状态来表示计数:

  

1、构造函数 

1
2
3
4
public CountDownLatch(int count) {
    if (count < 0) throw new IllegalArgumentException("count < 0");
    this.sync = new Sync(count);
}

通过传入一个数值来创建一个CountDownLatch,数值表示线程可以从等待状态恢复,countDown方法必须被调用的次数

 

2、countDown方法

1
2
3
public void countDown() {
        sync.releaseShared(1);
    }  

线程调用此方法对count进行减1。当count本来就为0,此方法不做任何操作,当count比0大,调用此方法进行减1,当new count为0,释放所有等待当线程。

 

3、await方法

(1)不带参数

1
2
3
public void await() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}

调用此方法时,当count为0,直接返回true,当count比0大,线程会一直等待,直到count的值变为0,或者线程被中断(interepted,此时会抛出中断异常)。

(2)带参数

1
2
3
4
public boolean await(long timeout, TimeUnit unit)
    throws InterruptedException {
    return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}

调用此方法时,当count为0,直接返回true,当count比0大,线程会等待一段时间,等待时间内如果count的值变为0,返回true;当超出等待时间,返回false;或者等待时间内线程被中断,此时会抛出中断异常。 

 

CountDownLatch实践

司机和工人,工人必须等到司机来了才能装货上车,司机必须得等到所有工人把货物装上车了之后才能把车开走。

工人类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Worker implements Runnable {
 
    private String workerCode;
 
    private CountDownLatch startLatch;
    private CountDownLatch latch;
 
    Worker(CountDownLatch startLatch, CountDownLatch latch, String workerCode) {
        this.startLatch = startLatch;
        this.latch = latch;
        this.workerCode = workerCode;
    }
 
    public void run() {
        try {
            startLatch.await();
            doWork();
            latch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
    private void doWork() {
        System.out.println("Worker " + workerCode + " is loading goods...");
    }
}

司机类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Driver {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch startLatch = new CountDownLatch(1);
        CountDownLatch latch = new CountDownLatch(10);
        ExecutorService executor = Executors.newFixedThreadPool(10);
 
        for(int i=0; i<10; i++) {
            executor.execute(new Worker(startLatch, latch, "worker" + i));
        }
 
        System.out.println("Driver is here.");
 
        startLatch.countDown();
 
        System.out.println("Workers get to work.");
 
        latch.await();
 
        System.out.println("Driver is ready to go.");
 
        executor.shutdown();
    }
}  

运行结果:

复制代码
Driver is here.
Workers get to work.
Worker worker0 is loading goods...
Worker worker1 is loading goods...
Worker worker2 is loading goods...
Worker worker3 is loading goods...
Worker worker4 is loading goods...
Worker worker5 is loading goods...
Worker worker7 is loading goods...
Worker worker9 is loading goods...
Worker worker8 is loading goods...
Worker worker6 is loading goods...
Driver is ready to go.
复制代码

 

完整工程代码请参考git:https://github.com/xuweijian/CountDownLatch.git

 

posted on   Will.Shun  阅读(5020)  评论(0编辑  收藏  举报

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示