公平锁和非公平锁 源码

ReentrantLock 提供了公平锁和非公平锁,只需要在构造方法中使用一个 boolean 参数即可。默认非公平锁。

ReentrantLock 类主要结构



ReentrantLock 内部有一个抽象类 Sync,继承了 AQS,同时Sync有两个实现类。这两个实现类就是公平锁 FairSync,是非公平锁NonFairSync。两把锁的主要区别在于lock 方法的实现。

AQS是基于模板模式的实现,不过它的模板模式写法有点特别,整个类中没有任何一个abstract的抽象方法,取而代之的是,需要子类去实现的那些方法通过一个方法体抛UnsupportedOperationException异常来让子类知道。


公平锁 FairSync

调用的是 AQS 的acquire方法,AQS 会回调子类的 tryAcquire 方法(模版模式,但是不是用的抽象方法),看看公平锁的tryAcquire实现。


主要逻辑:

  • 1、获取 state 变量,如果是 0,说明锁可以获取。
  • 2、判断 AQS 队列中是否有等待的线程,如果没有,就使用 CAS 尝试获取。获取成功后,将 CLH 的持有线程修改为当前线程。
  • 3、重入锁逻辑。
  • 4、如果失败,返回 false, AQS 会将这个线程放进队列,并挂起。

重点在判断 AQS 队列中是否有等待的线程,如果有,那么就相当于失败,放入队列并挂起。

非公平锁NonFairSync


不需要判断 AQS 队列中是否有等待的线程,直接去发起获取锁操作。如果获取失败,同样是通过模版模式,调取实现类的方法。




两个方法不同之处就在于是否判断aqs队列中是否有等待线程。抢不到再进入队列。等待他的前置节点唤醒他。这个过程是公平的。也就是进入队列了,行为就一样了。。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ReentrantLock 介绍 一个可重入的互斥锁,它具有与使用{synchronized}方法和语句访问的隐式...
    tomas家的小拨浪鼓阅读 4,092评论 1 4
  • 作者: 一字马胡 转载标志 【2017-11-03】 更新日志 前言 在java中,锁是实现并发的关键组件,多个...
    一字马胡阅读 44,182评论 1 32
  • 前言 上一篇文章《基于CAS操作的Java非阻塞同步机制》 分析了非同步阻塞机制的实现原理,本篇将分析一种以非同步...
    Mars_M阅读 4,834评论 5 9
  • 理解多线程的并发锁,可结合多进程的分布式锁(如Zookeeper的互斥锁、读写锁的实现原理),本质是相通的 介绍 ...
    jiangmo阅读 744评论 0 1
  • 创新是落后者的“特权”。不是落后者要学习领先者,而是领先者要学习落后者。 创业者最重要的一个素质,恰恰是明知道很可...
    喵皇后阅读 90评论 0 0