/*非公平锁 NonfairSync*/
/*锁的获取*/
public void unlock() {
sync.lock();
}
/**
* <p>
如果获取锁成功, 把同步器中的exclusiveOwnerThread设置为当前线程,获取锁失败的线程,则acquire方法,再次尝试获取锁
</p>
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1)) // 如果获取锁成功, 把同步器中的exclusiveOwnerThread设置为线程A
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); // 获取锁失败的线程,则执行acquire方法,再次尝试获取锁
}
/**
* CAS compareAndSwapInt方法参数:修改的对象、内存偏移量、修改后的期望值、待修改的值
*/
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update); //
}
/**
* 同步器中的exclusiveOwnerThread设置为线程A
*/
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
/**
* 该方法定义在AbstractQueuedSynchronizer队列同步器中,子类可直接使用。
* 子类重写tryAcquire方法,tryAcquire调用的是nonfairTryAcquire方法。
* 如果锁未获取成功,创建一个waiter(当前线程)后放到队列中。Node.EXCLUSIVE表示独占锁
*/
// AbstractQueuedSynchronizer
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) { // 如果当前state值为0,表示锁已释放,则线程可竞争锁
if (compareAndSetState(0, acquires)) { // 如果竞争锁成功,则将同步器中的exclusiveOwnerThread设置为当前线程
setExclusiveOwnerThread(current);
return true;
}
}
//如果不为0,意味着,锁已经被拿走了,但是,因为ReentrantLock是重入锁,是可以重复lock,unlock的,只要成对出现行。
// 这里还要再判断一次 获取锁的线程是不是当前请求锁的线程
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires; // 如果是的,累加在state字段上就可以了
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
/**
* 将线程放入等待队列中. 用当前线程去构造一个Node对象
*
*/
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)) { // 通过CAS修改尾节点为最新的节点,并返回下一个节点
pred.next = node;
return node;
}
}
enq(node); // 如果修改失败,意味着有并发,这个时候才会进入enq中死循环,“自旋”方式修改,直至修改成功
return node;
}
/**
* 该方法主要的作用是将当前线程挂起
*/
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;
}
// 否则,检查前一个节点的状态为,看当前获取锁失败的线程是否需要挂起
// 如果需要,借助JUC包下的LockSopport类的静态方法Park挂起当前线程。直到被唤醒
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed) // 如果有异常
cancelAcquire(node); // 取消请求,对应到队列操作,就是将当前节点从队列中移除
}
}
/*锁的释放,调用了AQS的release方法*/
public void unlock() {
sync.release(1);
}
/**
* 执行锁的释放
*/
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
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) {//因为是重入的关系,不是每次释放锁c都等于0,直到最后一次释放锁时,才通知AQS不需要再记录哪个线程正在获取锁。
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
/**
* 找到头节点,并通过LockSupport unpark方法唤醒线程
*/
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);
}
/*公平锁*/
/**
保证公平整体性能比较低,原因是会让活跃的线程得不到锁,进入等待状态,引起线程的上下文切换
PS:即使fair参数为true,tryLock()方法也是不保证公平的
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
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() {
// 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());
}