源码分析JDK8之AbstractQueuedSynchronizer


前言

源码分析我认为主要有两个作用:满足好奇心,我想每一个有追求的人都不会满足于仅仅做一个API Caller实现功能就好,我们也想知道它到底是怎么实现的;借鉴与升华,当我们明白了一个类的设计原理,在一定的情境下我们可以借鉴其设计哲学,甚至针对我们自己特殊的业务场景对其进行改良与优化。

下面我就以这篇文章开启我的源码阅读之旅。总体而言,我会从这个类基本结构入手,然后分析原理,再看看已有的应用,并进行分析与理解。

我之前一篇文章里提到过java的显示锁ReentrantLock。此外,如果你编写过并发程序那你一般也应该用过CountDownLatch,Semaphore等等,这些都是同步器,而它们都基于AbstractQueuedSynchronizer(简称AQS)实现的,那么我们今天就来看看这个牛逼的AQS是怎么实现这么多功能的。

首先打开IDEA,随便新建一个类,然后输入CountDownLatch,在它上面敲下Ctrl+B,就打开了CountDownLatch的源码,然后发现有一个非常重要的静态内部类Sync继承了AbstractQueuedSynchronizer,再次Ctrl+B,我们就打开了AQS的源码,马上就可以解开它的神秘面纱了,哼哼。

映入眼帘的首先就是大段大段的文档,大意就是这个类 提供了一个基于FIFO队列的实现了阻塞锁和相关同步器(信号量,事件等)的框架...... 读完了大概就了解这个类到底是怎么工作的了。下面我们开始分类型研究源码,当然不可能全部分析一遍,这里只把重点的列出来。


MySQL InnoDB 锁——官方文档翻译


个人认为学习MySQL最好的书面材料莫过于官方文档了,它不仅详细介绍了方方面面的使用方法,还讲解了原理,让你知其然并且知其所以然。这里就把官网的InnoDB Locking这一小节翻译过来,抛砖引玉。

InnoDB锁类型包括


一文理清21种设计模式:用实例分析和对比


设计模式无论是对于最底层的的编码实现还是较高层的架构设计都有着重要的指导作用。所谓光说不练假把式,今天我就把项目中常见的应用场景涉及到的主要设计模式及其相关设计模式总结一下,用实例分析和对比的方式在一片文章中就把最常见的21种设计模式梳理清楚。

Redis发布订阅

在项目中常常使用redis的发布/订阅功能,用来实现进程间通信甚至IM等业务。
使用 jedis 实现频道订阅的模式一般如下:

try( Jedis jedis =  RedisClient.getJedis() ) {
    JedisPubSub listener = new MySubListener();
    // 订阅
    jedis.subscribe(listener, "channel");
}


后端好书阅读与推荐(续四)


后端好书阅读与推荐系列文章:
后端好书阅读与推荐
后端好书阅读与推荐(续)
后端好书阅读与推荐(续二)
后端好书阅读与推荐(续三)
后端好书阅读与推荐(续四)

这里依然记录一下每本书的亮点与自己读书心得和体会,分享并求拍砖。

Docker生产环境实践指南

Docker生产环境实践指南 (豆瓣) https://book.douban.com/subject/26825958/

前面docker的基本概念和一些核心原理都看的差不多了,那么现在该关注一下具体的生产环境的使用方法了。

亮点:

  • 在生产环境中运行docker与在其它环境中相比,最主要的差异是需要在其安全性与稳定性上投入更多的注意力
  • 书中提到docker 容器与宿主机是通过IPtables实现的nat转换来进行通信,这点官网有说明 Docker container networking,然后就说了不适宜网络吞吐量有很高要求的应用(但是可以禁用Docker的NAT来提升网络性能),但是docker已经做出了一些努力,效果并不差,见:1,2,3
  • 书中对于docker相关常见的概念解释得非常清晰易懂,这一部分尤其适合初学者
  • docker生产环境最好的方式是将应用程序及其依赖预先打包成一个镜像,而包含数据库凭证等铭感信息在运行时动态添加(安全起见);常见流程是开发机上打包并推送到仓库,然后服务器从仓库拉取镜像,这种用例简单但是从工作流和安全角度看并不理想,更标准的做法是使用持续集成 / 持续交付系统在应用程序代码或者dockerfile发生变化时自动从新构建镜像


数据结构与算法——常用高级数据结构及其Java实现


前文 数据结构与算法——常用数据结构及其Java实现 总结了基本的数据结构,类似的,本文准备总结一下一些常见的高级的数据结构及其常见算法和对应的Java实现以及应用场景,务求理论与实践一步到位。

跳跃表

跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表。是一种随机化数据结构,基于并联的链表,其效率可比拟于红黑树和AVL树(对于大多数操作需要O(logn)平均时间),但是实现起来更容易且对并发算法友好。redis 的 sorted SET 就是用了跳跃表。

性质:

  1. 由很多层结构组成;
  2. 每一层都是一个有序的链表,排列顺序为由高层到底层,都至少包含两个链表节点,分别是前面的head节点和后面的nil节点;
  3. 最底层的链表包含了所有的元素;
  4. 如果一个元素出现在某一层的链表中,那么在该层之下的链表也全都会出现(上一层的元素是当前层的元素的子集);
  5. 链表中的每个节点都包含两个指针,一个指向同一层的下一个链表节点,另一个指向下一层的同一个链表节点;