一、概述
是JDK实现的一种可重入锁,能够实现公平和非公平锁。
二、实现接口
public class ReentrantLock implements Lock, java.io.Serializable
实现接口Lock
public interface Lock {
//获取锁,如果获取不到就会出于线程调度的目的禁用,并且直到获取锁
void lock();
//获取锁除非当前线程是中断的,如果获取不到,就会禁用,直到获取锁或者中断异常
void lockInterruptibly() throws InterruptedException;
//尝试获取锁,获取返回true,否则false
boolean tryLock();
//在时间段内,获取锁则返回true,如果获取失败则会禁用,直到获取锁或者中断或者时间到
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
//释放锁
void unlock();
//调用await 将自动释放锁,等待重新获取锁
Condition newCondition();
}
三、ReenTrantLock实现
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
//重点属性 提供所有执行机制的同步器
private final Sync sync;
//默认使用非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
//根据参数指定是否使用公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
public void lock() {
sync.lock();
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
//由于是可重入锁,可能同一线程持有多次
public void unlock() {
sync.release(1);
}
public Condition newCondition() {
return sync.newCondition();
}
//持有锁的数量
public int getHoldCount() {
return sync.getHoldCount();
}
//是否被当前线程持有
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
//是否已有线程持有锁
public boolean isLocked() {
return sync.isLocked();
}
//是否是公平锁
public final boolean isFair() {
return sync instanceof FairSync;
}
//持有锁的线程
protected Thread getOwner() {
return sync.getOwner();
}
//是否有线程在排队等待
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
//当前线程是否在等待队列中
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
//等待队列的长度
public final int getQueueLength() {
return sync.getQueueLength();
}
//获取等待队列,返回值为ArrayList
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
//TODO
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
//TODO
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
//TODO
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public String toString() {
Thread o = sync.getOwner();
return super.toString() + ((o == null) ?
"[Unlocked]" :
"[Locked by thread " + o.getName() + "]");
}
}
四、sync属性
继承抽象类AbstractQueuedSynchronizer,抽象队列同步器;
AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch…。
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
//由其子类NonfairSync、FairSync实现
abstract void lock();
//非公平锁尝试获取锁
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//getState是AQS提供的方法,在其内部维护了一个计数器state,用于记录获取锁的数量
int c = getState();
if (c == 0) {
//采用CAS判断在此代码运行期间有没有锁被获取了
if (compareAndSetState(0, acquires)) {
//设置排他锁线程为当前线程
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
//如果以获取锁的对象就是当前线程,则计数器+1
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//由于是当前线程,没有线程安全问题,无需使用CAS
setState(nextc);
return true;
}
return false;
}
//尝试释放锁
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
//计数器为0表示锁完全被释放,可以被其他线程获取
free = true;
setExclusiveOwnerThread(null);
}
//释放锁之前,其他线程不可能获取锁,所以无需CAS
setState(c);
return free;
}
//当前线程是否持有锁
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
// Methods relayed from outer class
//获取持有锁的线程
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
//当前线程持有锁的数量
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
//锁是否已被某个线程持有
final boolean isLocked() {
return getState() != 0;
}
/**
* 反序列化,重置为无锁状态
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
五、公平锁和非公平锁
非公平锁
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
//CAS第一次尝试获取锁,由于是非公平锁,所以先尝试获取,否则需要加入队列
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
//进入这里,说明当前锁被某个线程持有,也可能是自己,开始获取锁;AQS实现
acquire(1);
}
//尝试获取锁,调用父类Sync中非公平锁获取
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
公平锁
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
//直接使用AQS实现的获取锁方法,严格按照先加入同步队列,后获取锁的顺序
final void lock() {
acquire(1);
}
//尝试获取锁,无论是否成功都会立即返回
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//AQS中实现,判断队列中是否有优先级更高的线程
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
AQS中代码
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
//TODO
// h = t 表示队列为空;头结点是当前持有锁的节点,所以优先级最高的是头结点的下一个节点
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}