公平的锁会把权限给等待时间最长的线程来执行,非公平则获取执行权限的线程与线程本身的等待时间无关
默认初始化ReentrantLock使用的是非公平锁,当然可以通过指定参数来使用公平锁当执行获取锁时,实际就是去执行 Sync 的lock操作:
public ReentrantLock() { sync = new NonfairSync();}复制代码
ReentrantLock的tryLock()与tryLock(long timeout, TimeUnit unit):AbstractQueuedSynchronizer无论是公平锁还是非公平锁,它们的实现都依赖于AbstractQueuedSynchronizer,它提供了一个基于先进先出等待队列 实现block locks和synchronizers的框架。特性如下
public boolean tryLock() {//本质上就是执行一次非公平的抢锁 return sync.nonfairTryAcquire(1); }复制代码有时限的tryLock核心代码是 sync.tryAcquireNanos(1, unit.toNanos(timeout));,由于有超时时间,它会直接放到等待队列中,他与后面要讲的AQS的lock原理中acquireQueued的区别在于park的时间是有限的,详见源码 AbstractQueuedSynchronizer.doAcquireNanos
从这里可以看到,无论锁是公平锁还是非公平锁,只要被放入了等待队列,此时的执行依然是谁先等待就先执行谁 ,非公平锁体现在新来的线程会无视已经等了的线程,可以优先去抢锁,所以公平体现在第一次参与抢锁的线程会去等待已经在等待队列中的线程,非公平并不是说从已经在等待的线程队列里面随便选一个shouldParkAfterFailedAcquire的源码如下

奈斯
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |