Java中的阻塞队列(3)同步计数器

简介: 9、同步计数器 CountDownLatch    这是一个同步的辅助类,实现原理为AbstractQueuedSynchronizer抽象队列化同步器图9-1    方法介绍:        1、CountDownLatch(in...

9、同步计数器 CountDownLatch

    这是一个同步的辅助类,实现原理为AbstractQueuedSynchronizer抽象队列化同步器

img_74d435bbedd7ec220def21831331326d.png
图9-1

    方法介绍:

        1、CountDownLatch(int count):构造,并给定计数初始化

        2、await():当前线程在锁存器倒计数到零之前一直等待,除非线程被中断

        3、await(long, TimeUnit):当前线程在锁存器倒计数到零之前一直等待,除非线程被中断或者超出指定时间

        4、countDown():计数减一

        5、getCount():获取当前计数

    至于例子,就通过之前写过的并发单元测试历程就可以

img_3a7541a9b742f625c769b0ef73c2a52c.png
图9-2

    至于实现原理,我们看源码会发现,其实CountDownLatch也是调用了一个AbstractQueuedSynchronizer抽象队列化同步器

10、AbstractQueuedSynchronizer抽象队列化同步器

    这是一个java.util.concurrent的核心组件之一,提供了一个基于FIFO的队列,用于构建锁或者其他相关同步装置的基础框架

    首先看继承结构如图10-1

img_f70a75b881d09306079eb12d45d81d67.png
图10-1

这个继承结构是非常简单的,但是里面包含的方法就 emmmmmmm。。。有点多了,而且这是一个抽象类,但是里面却找不到任何一个抽象方法,想要使用就需要继承这个类才行,AbstractQueuedSynchronizer分为两种模式,排他模式和共享模式,也可以两个模式共存,排他模式时其他线程试图获取该锁将无法取得成功,共享模式则可以同时成功。

    其中的方法子类可以适当的重新定义:

        1、tryAcquire(int)、tryRelease(int):试图在排他模式下获取/销毁对象状态

        2、tryAcquireShared(int)、tryReleaseShared(int):试图在排他模式下获取/销毁对象状态

        3、isHeldExclusively():如果对于当前正在调用的线程,同步是以排他方式进行的,则返回true,判断当前正在执行的线程是否以排他模式进行的

        4、getState()、setState(int)、compareAndSetState(int, int):通过这种方式来改变同步状态

    我们这边提取一个官方的demo,加以说明一下

img_4d35a9982d6f782024c9aabe5699a6ee.png
img_0be67706809d9d3ca814ed91973f76ce.png
img_32da6dafc3d81c1bb9325cc7d9fa9586.png

        以下为Lock对象的实现方法

img_77c951a09e326b682eec2539ad3c6431.png
img_cec46d47f346e4e794915faa6fedf9b8.png
普通重入锁的执行过程

11、同步计数器Semaphore:

    这个其实就是维护了一个许可集合,其实就是在高并发下,允许几个线程同时运行,其余线程放入队列,具体的应用场景就是线程池,这个放在后面说明。

    实现原理其实也很简单,底层也是通过AQS的方式,

12、同步计数器CyclicBarrier

    这个需要对比着CountDownLatch来看

    CountDownLatch:一个线程(或者多个线程),等待另外n个线程完成某个事情之后才能执行

    CyclicBarrier:n个线程互相等待,任何一个线程完成之前,其他的线程都必须等待

    来看一个例子

img_5644124b9a2486d054932f1ed63683c8.png
img_778afe723da6f6ca1d30c4e504032c94.png
img_4b04be275b1fa0ee8e5161f9364976f3.png

    可以看到,三个子线程先执行,一直到三个线程都await的时候,主线程开始执行,主线程执行完毕之后,三个线程开始执行await后面的任务。

    至于源码的解读。。。。。。。还是算了吧。。。

相关文章
|
5月前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
Java多线程同步大揭秘:synchronized与Lock的终极对决!
99 5
|
5月前
|
存储 监控 安全
一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这篇文章是Java面试第三天的笔记,讨论了线程安全、Thread与Runnable的区别、守护线程、ThreadLocal原理及内存泄漏问题、并发并行串行的概念、并发三大特性、线程池的使用原因和解释、线程池处理流程,以及线程池中阻塞队列的作用和设计考虑。
|
2月前
|
Java 调度
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
|
3月前
|
存储 消息中间件 安全
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
【10月更文挑战第9天】本文介绍了如何利用JUC组件实现Java服务与硬件通过MQTT的同步通信(RRPC)。通过模拟MQTT通信流程,使用`LinkedBlockingQueue`作为消息队列,详细讲解了消息发送、接收及响应的同步处理机制,包括任务超时处理和内存泄漏的预防措施。文中还提供了具体的类设计和方法实现,帮助理解同步通信的内部工作原理。
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
|
3月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
66 1
|
5月前
|
安全 Java 开发者
Java多线程同步:synchronized与Lock的“爱恨情仇”!
Java多线程同步:synchronized与Lock的“爱恨情仇”!
93 5
|
5月前
|
Java 程序员
从0到1,手把手教你玩转Java多线程同步!
从0到1,手把手教你玩转Java多线程同步!
52 3
|
5月前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
Java多线程同步实战:从synchronized到Lock的进化之路!
110 1
|
5月前
|
存储 算法 Java
Java 中的同步集合和并发集合
【8月更文挑战第22天】
58 5
|
5月前
|
安全 Java
Java 中同步 ArrayList 的详细指南
【8月更文挑战第23天】
96 1