写点什么

druid 源码学习八

作者:Nick
  • 2022 年 5 月 18 日
  • 本文字数:1265 字

    阅读完需:约 4 分钟

druid源码学习八

一、引言

今天继续学习王巍巍老师 druid 完整逻辑流程图,CreateConnectionThread 的逻辑。这篇注意关注 CountDownLatch、自旋锁两个概念进行展开学习。


二、关于 CountDownLatch 类的学习。

同样看 jdk api 看看作者的解释。


允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。A CountDownLatch 用给定的计数初始化。 await 方法阻塞,直到由于 countDown()方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的 await 调用立即返回。 这是一个一次性的现象 - 计数无法重置。如果您需要重置计数的版本,请考虑使用 CyclicBarrier 。


A CountDownLatch 是一种通用的同步工具,可用于多种用途。 一个 CountDownLatch 为一个计数的 CountDownLatch 用作一个简单的开/关锁存器,或者门:所有线程调用 await 在门口等待,直到被调用 countDown()的线程打开。一个 CountDownLatch 初始化 N 可以用来做一个线程等待,直到 N 个线程完成某项操作,或某些动作已经完成 N 次。


CountDownLatch 一个有用的属性是,它不要求调用 countDown 线程等待计数到达零之前继续,它只是阻止任何线程通过 await ,直到所有线程可以通过。


看这翻译真有种想要重新再翻译一遍 jdk 的冲动。可惜英语水平有限,不然也不至于来看这中文版的 API 了。


其实可以直接从类名来猜测该类的意思:


CountDownLatch 中 count down 是倒数的意思,latch 则是门闩的含义。所以可以理解为倒数的门栓,是不是有点“三二一,芝麻开门”的感觉。


CountDownLatch 在构造 CountDownLatch 的时候需要传入一个整数 n,在这个整数“倒数”到 0 之前,主线程需要等待在门口,而这个“倒数”过程则是由各个执行线程驱动的,每个线程执行完一个任务“倒数”一次。


该类总体来说比较简单,方法也比较少,如下 API 截图:



重点两个方法:


countDown()方法用于使计数器减一,其一般是执行任务的线程调用


await()方法则使调用该方法的线程处于等待状态,其一般是主线程调用。


总结来说,CountDownLatch 的作用就是等待其他的线程都执行完任务,必要时可以对各个任务的执行结果进行汇总,然后主线程才继续往下执行。

三、自旋锁

3.1 什么是自旋锁

自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。自旋一般就是 while 循环,持续进行条件比较,比如 Java 的 CAS 操作。

3.2 自旋锁的优缺点

优点:自旋的优点是线程还是 Runnable 的,只是在执行空代码,而不是进入线程挂起或睡眠状态。线程一旦进入阻塞(Block),再被唤醒的代价比较高,性能较差。这时会考虑使用自旋锁的方式。


缺点:缺点是如果情况很悲观,长时间获取锁不成功而一直自旋,会给 CPU 带来很大的开销。


一般推荐的自旋方案是先自旋一段时间,还没拿到锁就进入阻塞。JVM 在处理 synchrized 实现时就是采用了这种折中的方案,并提供了调节自旋的参数。

四、总结

本篇我们通过学习 CreateConnectionThread 类,回顾学习了 CountDownLatch 以及自旋锁相关内容。


参考:

https://www.jianshu.com/p/128476015902

https://zhuanlan.zhihu.com/p/466667138

https://blog.51cto.com/u_3664660/3214958

发布于: 刚刚阅读数: 2
用户头像

Nick

关注

终身学习,向死而生 2020.03.18 加入

得到、极客时间重度学习者,来infoQ 是为了输出倒逼输入

评论

发布
暂无评论
druid源码学习八_Apache Druid_Nick_InfoQ写作社区