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

9、同步计数器 CountDownLatch

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

Java中的阻塞队列(3)同步计数器_第1张图片
图9-1

    方法介绍:

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

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

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

        4、countDown():计数减一

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

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

Java中的阻塞队列(3)同步计数器_第2张图片
图9-2

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

10、AbstractQueuedSynchronizer抽象队列化同步器

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

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

Java中的阻塞队列(3)同步计数器_第3张图片
图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,加以说明一下

Java中的阻塞队列(3)同步计数器_第4张图片
Java中的阻塞队列(3)同步计数器_第5张图片
Java中的阻塞队列(3)同步计数器_第6张图片

        以下为Lock对象的实现方法

Java中的阻塞队列(3)同步计数器_第7张图片
Java中的阻塞队列(3)同步计数器_第8张图片
普通重入锁的执行过程

11、同步计数器Semaphore:

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

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

12、同步计数器CyclicBarrier

    这个需要对比着CountDownLatch来看

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

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

    来看一个例子

Java中的阻塞队列(3)同步计数器_第9张图片
Java中的阻塞队列(3)同步计数器_第10张图片
Java中的阻塞队列(3)同步计数器_第11张图片

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

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

你可能感兴趣的:(Java中的阻塞队列(3)同步计数器)