public void lock() {
sync.lock();
}
这是lock的源码,调用的其实是sync这个对象的lock函数,而sync是ReentrantLock内部类Sync的一个对象实例,他有两种实现NonfairSync(非公平锁)和FairSync(公平锁)
先看公平锁的lock函数
final void lock() {
acquire(1);
}
只有一行代码,调用的是AQS的acquire函数
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
按流程,先进入tryAcquire
protected final boolean tryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取同步器的状态
int c = getState();
//如果状态为0,进入获取锁的操作
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
//获取锁成功,设置独占锁为当前线程
setExclusiveOwnerThread(current);
return true;
}
}//如果状态不为0,则判断是否为已经获得锁的对象进行重入锁操作
else if (current == getExclusiveOwnerThread()) {
//如果是重入锁操作则为状态进行累加操作
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
//获取锁失败返回false
return false;
}
在获取锁的时候有两步核心操作hasQueuedPredecessors(判断当前等待获取锁的线程队列是否为空)和compareAndSetState(将同步器状态标记为accquires)
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;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
如果当前没有线程在等待锁则返回true,如果有则返回false
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
调用unsafe对象的cas函数为同步器的状态进行修改,确保该操作为原子操作(同意时间若有多个线程进行该操作则只有一个线程返回成功)
这两步完成以后,就可以将当前线程标记为独占线程,该线程释放锁之前,再有线程来尝试获取锁都会进入下一步acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
先看addWaiter
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
将当前线程封装成Node对象,判断tail对象是否为空,如果不为空则调用原子操作compareAndSetTail,将该节点设为tail,如果该操作失败了,则调用enq函数
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
该函数为一个死循环,如果没有tail则新建head同时设置head为tail,然后一直循环到这个节点加入队列为止,加入成功后再将该节点返回出来,进入下一步操作acquireQueued
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
//获取上一节点
final Node p = node.predecessor();
//如果上一节点为头节点,则再次尝试获取锁
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
可以看到这个函数里也有一个死循环,然后有两个关键函数shouldParkAfterFailedAcquire(获取锁失败后是否应该挂起)和parkAndCheckInterrupt(挂起并检查中断状态)
先看parkAndCheckInterrupt
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
挂起当前线程,并返回了线程中断状态
然后是shouldParkAfterFailedAcquire
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
/*
* This node has already set status asking a release
* to signal it, so it can safely park.
*/
return true;
if (ws > 0) {
/*
* Predecessor was cancelled. Skip over predecessors and
* indicate retry.
*/
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
/*
* waitStatus must be 0 or PROPAGATE. Indicate that we
* need a signal, but don't park yet. Caller will need to
* retry to make sure it cannot acquire before parking.
*/
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
非公平锁的lock
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
可以看到他会先尝试修改一下状态,如果成功就直接设置当前线程为独占线程
他的acquire也跟公平锁不同
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
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;
}
对比公平锁,非公平锁少了hasQueuedPredecessors这一个判断,他在尝试获取锁的时候不会判断当前是否有线程处于等待状态
public void unlock() {
sync.release(1);
}
unlock调用的是同步器的release函数
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
先调用tryRelease函数,如果返回成功,则唤醒头节点线程
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
将状态值减去要释放的值,结果为零且执行tryrelease这个函数的当前线程为同步器的独占线程则释放成功,将独占线程置为null,状态置为0
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)
compareAndSetWaitStatus(node, 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 t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}
先找head节点的next节点,如果其为空或者waitStatus大于0则从tail节点开始往回遍历,找到排在最起码的waitStatus大于0的节点,调用LockSupport.unpark唤醒该节点