记录一下,今天学java并发编程的工具类写一下自己对CountDownLatch 类的理解 类本身的作用,类似于waitnotify,使线程进入阻塞并唤醒,达到线程通信的目的, 看一下实现原理

内部使用了同步类容器也就是AQS,Sync对象 ,count参数是指多线程需要唤醒的次数,内部维护了一个state属性就是count传入的属性, 可以当作一个计数器,如果为负数会抛出参数异常 。 然后实例化sync对象。

![](http://i2.51cto.com/images/blog/201811/21/de976d787751fa897a6867495b8747c4.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

线程阻塞方法

判断线程是否是中断,如果中断抛出异常,正常情况下不会中断

主要调用tryAcquireShared方法 判断state的值是否为0,0则返回1表示该线程被唤醒该判断的意义在于 “进入阻塞时先尝试一次是否可以被立即唤醒,如果能则继续执行,是非公平操作会先抢占一次资源,如果是公平操作则直接进入等待队列 ”

接下来调用 doAcquireSharedInterruptibly 方法的addWaiter 将线程进行入队列(因为会存在多个线程进入阻塞) 唤醒时根据先进先出的顺序依次唤醒,队列为链表结构将其加入到最后一个节点中。

然后线程进for循环空转的阻塞状态,首先判断等待队列的头节点是否是当前线程 ,是则在调用tryAcquireShared判断是否被唤醒如果唤醒则在队列中删除当前线程,继续执行程序,其他for循环中的阻塞线程也会依照队列依次唤醒。 parkAndCheckInterrupt 方法内部则中断线程调用释放资源保证程序性能 。

线程阻塞方法结束, 下面看一下countDown线程唤醒方法

该方法调用了 tryReleaseShared 进行State的减一

重点 ,同步类容器通过用CAS方法保证原子性操作,回调用 compareAndSetState 尝试将期望值改为 State-1后的值,该方法不会阻塞,如果此时存在并发操作则返回false,for循环继续调用直到该操作成功 。如果state为0时表示唤醒成功 ,其余阻塞线程根据队列一次调用。