转载
https://www.cnblogs.com/liqiangchn/p/11960944.html
简单而言
AQS内部维护了这样一个CLH队列。这样,只要具体的锁的实现利用这个队列(调用acquire release)就可以了。tryAcquire只用来抢头部节点。aquire才牵扯到入队的操作。
acquire的第一步,尝试CAS直接修改状态。
如果失败了,那就老老实实去排队吧。但是队尾显然也不是这么好加的,就是用自旋的方式不断尝试一直自己到队尾为止。
获取失败的线程,加入到同步队列的队尾;加入到队列中后,如果当前节点的前驱节点为头节点再次尝试获取同步状态
如果头节点的下一个节点尝试获取同步状态失败后,会进入等待状态
如果抢占成功,那么肯定需要释放,当前线程去唤醒后面继续的节点
后续节点唤醒成功。当前头节点出列。当前后续节点变成头节点,并拥有同步状态。
如果是非公平锁,我们其实是允许这样插队的
另外注意到JUC内部维护了ConditionObject这个public的内部类。既然不是static的,意味着他需要外部对象才能存在。说白了他就是模仿Object wait/notify的实现。