之前系列文章都在叙述java线程池的设计以及实现机制,没有涉及java并发编程的锁机制,这是因为锁机制与线程池是相对独立的内容,自成体系,可以把锁机制当做线程池的一个基础组件,想黑盒一样使用它。

可我们如何去设计这样的一个黑盒,这样的一把锁?首先我们先了解清楚我们对锁的基本需求。

程序需要用到锁,说明程序中有多个线程(进程)存在共同竞争的资源,这样的资源可以包括一个共享变量,共享文件等。就线程池来看,这样的资源就包括线程池的代表状态和工作线程数的ctl,工作队列,任务队列等,这些资源都被工作线程和调用线程所共享,为保证程序正常可控的运行,就需要一套机制对这些资源进行协调保护。

这样的机制就是我们要讲的锁机制,在java得世界里,锁机制就包括语言级别的synchonized关键字提供的锁以及java并发包里提供的改造的CLH锁。

先说synchonized的锁,原理是使用了monitor模式,内置一个条件队列,加锁和释放锁都提供指令级别的操作,而且做到自动化,无需手动操作,后期版本还加入锁的优化,提供轻量级锁,可重入锁,重量级锁的相互的升级与降级的转化机制,提高了并发的性能。

而CLH锁则是并发包里提供的锁实现方式,通过自我编程方式实现的一把锁,这把锁实现的原理简单来讲就是一个state共享变量加一个同步队列,附带有多个条件队列,基于此,提供共享锁与独占锁的实现,公平锁与非公平锁的实现以及可重入锁的实现,后期其他锁像信号量,闭锁等都是扩展于state字段来满足不同的锁需求。而各种CLH锁实现依赖于原子操作CAS和基本同步器AQS.

这一篇先大体理清楚锁机制的分类和基本功能实现,以下篇章则会详细介绍CLH锁的实现细节。