RentrantLock总览
ReentrantLock是一个独占式的锁,支持重入.里面实现了公平锁与非公平锁;
其中ReentrantLock支持可公平锁与非公平锁,最顶层的父类是AQS.获取锁阻塞释放全部都是通过AQS来实现.接下来详细说明这些是怎么实现的.
Sync
继承自AQS
abstract void lock();
抽象方法,让子类也就是两个公平和非公平类来实现.
boolean nonfairTryAcquire(int acquires) ;
此为尝试获取非公平锁,非公平锁的实现就是首先CAS替换看自己是否能够获得锁,如果能够获得,则设置为拥有锁,如果不行,返回false;
1 | abstract static class Sync extends AbstractQueuedSynchronizer { |
boolean tryRelease(int releases)
释放掉指定的资源.如果当前线程没有拥有锁,则抛出异常.
1 | abstract static class Sync extends AbstractQueuedSynchronizer { |
boolean isHeldExclusively()
表明当前线程是否是独占锁
1 | protected final boolean isHeldExclusively() { |
公平锁
ReentrantLock实现了两种锁,一种是非公平的,一种是公平的.两个的区别在于公平锁总是按照先来就先获得锁,非公平锁是谁抢到就算谁的.接下来看公平锁的实现:
lock
锁主要是通过acquire()实现锁住,acquire(1)方法是AQS中定义好的方法,acquire首先会调用自己所实现的tryacquire()方法,如果不成功则加入队列中,成功就直接获取到锁.
1 | final void lock() { |
这个方法如果有不了解,可以先去看我另一篇文章AQS详解
boolean tryAcquire(int acquires)
首先判断锁状态是否为0,如果为0,在判断阻塞队列中是否有前驱,如果没有前驱则设置此线程为拥有锁的线程.如果状态不为0,查看是否是自己拥有锁,如果不是返回false;
1 | static final class FairSync extends Sync { |
非公平锁
非公平锁与公平所实现基本一样,但是是首先直接去获取锁,如果获取不到则加入队列,获取到就已经用有锁.
非公平锁有一点就是能够极大的提高系统吞吐量,公平所因为是先来先获得锁,所以在切换锁的时候会有很大的系统调度开销,而非公平锁是直接抢占,所以不会有很大的系统开销.但是可能会造成线程饥饿
其他:
主要的一些方法都是通过调用内部类Sync的方法实现的.其实也就是用AQS定义好的框架来进行实现.这里就不一一说明了.有兴趣可以自己去看看源码