AQS思想
AQS全名AbstractQueuedSynchronizer(抽象队列同步器),是一种java自带的synchronized关键字之外的锁机制。
AQS定义了一个核心的共享资源 volatile int state,如果一个线程通过CAS 尝试获取共享资源成功,则认为该线程获取锁成功。如果获取失败,则将线程封装成 Node 放入 CLH队列(一种双向队列)中,并将线程阻塞,直到获取锁的线程施放资源后,一一唤醒CLH队列中的线程。
不同的同步器争夺锁的方式也不同,同步器只需要实现如何获取和释放共享资源state即可。至于CLH队列的维护则由AQS完成。
ReentrantLock源码阅读
而ReentrantLock则是对AQS的一种应用,下面开始对ReentrantLock的源码阅读分析。
ReentrantLock lock = new ReentrantLock(false);//false:非公平锁,true:公平锁
lock.lock() //加锁
lock.unlock() //解锁
非公平锁:
public class ReentrantLock implements Lock, java.io.Serializable {
private final Sync sync;
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
static final class NonfairSync extends Sync {
final void lock() {
if (compareAndSetState(0, 1)) //尝试通过cas获取锁,cas操作成功将标志当前线程为获取到锁的线程
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);//调回AbstractQueuedSynchronizer.acquire(int arg)
}
//父类AbstractQueuedSynchronizer.acquire()中调用本方法
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
abstract void lock();
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//通过state的值判断锁是否可以被获取
if (c == 0) {
if (compareAndSetState(0, acquires)) {
//标志锁的所有者
setExclusiveOwnerThread(current);
return true;
}
}
//如果锁已经被锁线程占有,state = state + 1,表示线程获取锁的次数
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;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//存在线程重入的情况,只有state等于0才算释放锁成功
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
public void unlock() {
sync.release(1);
}
}
public abstract class AbstractQueuedSynchronizer{
//获取独占锁,参数指的是获取锁的数量
public final void acquire(int arg) {
/*
* tryAcquire:真正执行获取锁的流程
* addWaiter:获取锁失败,那么就会将该线程封装成Node节点放入等待队列中
* acquireQueued:获取锁失败,准备阻塞等待获取锁
* selfInterrupt:如果线程挂起时是被中断唤醒的,需要再重新设置中断标志
*/
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//独占模式
selfInterrupt();
}
private Node addWaiter(Node mode) {
//将当前线程封装成Node
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
//进入这里说明队列已初始化完毕,则将新加入的Node设为tail
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//该方法的目的是保证节点插入成功
enq(node);
return node;
}
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;
}
}
}
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
//获取当前节点的前驱节点
final Node p = node.predecessor();
//如果前驱节点是head节点才会进行再一次获取锁,这里再一次获取锁的目的有可能这时锁已经释放了
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
//返回中断标志,该标志表明线程阻塞时是否被中断过
return interrupted;
}
/*
* shouldParkAfterFailedAcquire: 如果前驱节点不是head节点,则判断该线程是否应该进行阻塞
* parkAndCheckInterrupt: 如果前驱节点的status是-1(singal),则对线程进行阻塞
*/
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
//将线程从等待队列中移除
cancelAcquire(node);
}
}
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
/*
* 如果前驱节点的status是-1(singal),则该线程可以被挂起
*/
return true;
if (ws > 0) {
/*
* 如果前驱节点的status是cancel状态,则将该节点从队列中移除
*/
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
/*
* 如果前驱节点的status是0,那么需要将其设置成singal,然后在下一轮循环中将该线程挂起
*/
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
//释放锁成功,唤醒后继节点
unparkSuccessor(h);
return true;
}
return false;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
/*
* 如果head节点是singal,需要重新设置为0,目的是清除同步状态,因为锁的状态已发生变化,需要重新设置状态
*/
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next;
//如果head的后继节点是cancel,则需要一直往后找,直到找到一个正常的节点
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);
}
}
非公平锁,唯一区别的只有t ryAcquire(int acquires)
public class ReentrantLock implements Lock, java.io.Serializable {
abstract static class Sync extends AbstractQueuedSynchronizer {、
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//与非公平锁的区别就是获取锁之前会判断在等待队列节点是否有正在等待中的节点,没有的才会进行cas获取
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;
}
}
public final boolean hasQueuedPredecessors() {
// 判断当前节点是否有前驱节点
Node t = tail;
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
}