ReentrantLock
lock
- lock调用ReentrantLock中lock调用sync.acquire
/** Synchronizer providing all implementation mechanics */
private final Sync sync;
public void lock() {
sync.acquire(1);
}
- sync.acquire(1)则调用AbstractQueuedSynchronizer(AQS)下的acquire方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
//如果没有上锁,则将线程放入等待队列中
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
- 将线程放入等待队列中的两个方法acquireQueued与addWaiter
先看addWaiter
/**
* Creates and enqueues node for current thread and given mode.
*
* @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
* @return the new node
* 为当前线程和给定模式创建和排队节点。
* 参数:模式– Node.EXCLUSIVE 用于独占,Node.SHARED 用于共享
* 返回:新节点
*/
private Node addWaiter(Node mode) {
//创建一个新节点
Node node = new Node(mode);
//直到加入队列为止
for (;;) {
//将尾节点用一个节点存储下来
Node oldTail = tail;
//将新节点加入链表尾部
if (oldTail != null) {
node.setPrevRelaxed(oldTail);
if (compareAndSetTail(oldTail, node)) {
oldTail.next = node;
return node;
}
} else {
initializeSyncQueue();
}
}
}
/**
* Acquires in exclusive uninterruptible mode for thread already in
* queue. Used by condition wait methods as well as acquire.
*
* @param node the node
* @param arg the acquire argument
* @return {@code true} if interrupted while waiting
* 以独占不间断模式获取已在队列中的线程。由条件等待方法和获取使用。
* 参数:节点——节点arg – 获取参数
* 回报:如果在等待时被打断,则为true
*/
final boolean acquireQueued(final Node node, int arg) {
boolean interrupted = false;
try {
for (;;) {
//获取该节点的前驱节点
final Node p = node.predecessor();
//判断是否是头节点,并尝试获取锁,等第一个节点释放锁就能获取锁
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node))
interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
if (interrupted)
selfInterrupt();
throw t;
}
}
- 然后调用ReentrantLock中的静态内部类NonfairSync中tryAcquire,继承于Sync
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
- 然后调用ReentrantLock中静态内部类Sync中的nonfairTryAcquire方法,该类继承于AbstractQueuedSynchronizer
/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
* 执行不公平的 tryLock。 tryAcquire 在子类中实现,但两者都需要对 trylock 方法进行非公平尝试。
*/
@ReservedStackAccess
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取当前线程的状态,看是否上锁
int c = getState();
//判断当前线程是否上锁
if (c == 0) {
//将当前线程的状态从0-》1
if (compareAndSetState(0, acquires)) {
//设置当前线程独立占用锁
setExclusiveOwnerThread(current);
//返回结果
return true;
}
}
//当前线程已上锁,重入上锁
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
lock流程过程图
ReentrantLock的lock调用流程如下:
- 调用ReentrantLock中的lock方法,而lock方法中语句sync.acquire()调用AbstractQueuedSynchronizer类中的acquire()方法
- acquire() 方法调用ReentrantLock中的静态内部类NonfairSync中的tryAcquire(arg)方法,类NonfairSync继承于Sync类
- tryAcquire方法中代用Sync类中的nonfairTryAcquire()方法,主要用于设置必要的参数
unlock
- 第一步调用unlock,调用Sync中的release方法
/** Synchronizer providing all implementation mechanics */
private final Sync sync;
/**
* Attempts to release this lock.
*
* <p>If the current thread is the holder of this lock then the hold
* count is decremented. If the hold count is now zero then the lock
* is released. If the current thread is not the holder of this
* lock then {@link IllegalMonitorStateException} is thrown.
*
* @throws IllegalMonitorStateException if the current thread does not
* hold this lock
*/
public void unlock() {
//释放一个
sync.release(1);
}
- 第二步: sync.release(1);调用AQS中的release方法
/**
* Releases in exclusive mode. Implemented by unblocking one or
* more threads if {@link #tryRelease} returns true.
* This method can be used to implement method {@link Lock#unlock}.
*
* @param arg the release argument. This value is conveyed to
* {@link #tryRelease} but is otherwise uninterpreted and
* can represent anything you like.
* @return the value returned from {@link #tryRelease}
*/
public final boolean release(int arg) {
//尝试将持有当前锁的对象给释放掉
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
//如果没有将当前线程释放掉,则将查找本线程在链表中的下一个节点,将其唤醒去抢占锁
unparkSuccessor(h);
return true;
}
return false;
}
- 如果没有将当前线程释放掉,则将查找本线程在链表中的下一个节点,将其唤醒去抢占锁
/**
* Wakes up node's successor, if one exists.
* 唤醒节点的后继者(如果存在)。
* 参数:节点——节点
* @param node the node
*/
private void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
int ws = node.waitStatus;
if (ws < 0)
node.compareAndSetWaitStatus(ws, 0);
/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node p = tail; p != node && p != null; p = p.prev)
if (p.waitStatus <= 0)
s = p;
}
if (s != null)
LockSupport.unpark(s.thread);
}
- 第三步:调用ReentrantLock中的tryRelease尝试将其释放
@ReservedStackAccess
protected final boolean tryRelease(int releases) {
//将当前线程状态减1
int c = getState() - releases;
//判断是否是当前线程所占的锁
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
//设置对当前独占访问权限者为null
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
/**
* 设置当前拥有独占访问权限的线程。 null参数表示没有线程拥有访问权限。此方法不会强加任何同步或volatile字段访 * 问。
* 参数:线程——所有者线程
*/
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}