ReentrantLock
构造函数:
public ReentrantLock() {
sync = new NonfairSync();
}
加锁:
//ReentrantLock的lock方法
public void lock() {
sync.lock();
}
//sync的lock方法,sync其实就是基于AQS实现的一个类
final void lock() {
//如果CAS从0设为1成功,说明获取到锁
if (compareAndSetState(0, 1))
//将exclusiveOwnerThread变量设置为当前线程
setExclusiveOwnerThread(Thread.currentThread());
else
//获取锁失败
acquire(1);
}
public final void acquire(int arg) {
//tryAcquire再次尝试获取锁,失败返回false
//acquireQueued内有一个循环用于唤醒后tryAcquire
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
//如果是队列第一个线程节点则tryAcquire,及尝试获取锁
if (p == head && tryAcquire(arg)) {
//获取成功,设置为head
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//shouldParkAfterFailedAcquire将p设置为SIGNAL
//parkAndCheckInterrupt将线程挂起
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
公平锁的tryAcquire
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//hasQueuedPredecessors用于判断同步队列是否有节点,有的话新来的线程就不会去竞争锁,以达到公平的目的
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;
}
非公平锁的tryAcquire
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;
}
1、公平锁能保证:老的线程排队使用锁,新线程仍然排队使用锁。
2、非公平锁保证:老的线程排队使用锁;但是无法保证新线程抢占已经在排队的线程的锁。
释放锁:
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
//释放掉arg个state
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
//唤醒同步队列的第一个线程节点,使其开始for循环,unparkSuccessor不再分析,和CountDownLatch一样
unparkSuccessor(h);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
//state减去releases
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;
}
newCondition()分析:
final ConditionObject newCondition() {
return new ConditionObject();
}
调用等待方法
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
//将此线程加入条件队列(等待队列),单向链表
Node node = addConditionWaiter();
//释放掉state,并唤醒同步队列的第一个线程节点
int savedState = fullyRelease(node);
int interruptMode = 0;
//退出循环的条件:1.该节点在同步队列(即被其他线程signal,转移到了同步队列)2.线程被中断也可以退出此循环
while (!isOnSyncQueue(node)) {
//线程挂起,挂起后可以由unpark或interrupt结束挂起
LockSupport.park(this);
//
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
//线程从await状态被signal后,尝试获取锁,和ReentrantLock获取锁一样,该方法返回的是此线程是否被interrupt了
//如果此线程被interrupt,则执行&&后面的
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
//reportInterrupt
reportInterruptAfterWait(interruptMode);
}
private Node addConditionWaiter() {
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters();
t = lastWaiter;
}
//等待队列里的Node都是Condition状态的
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
//是头结点
firstWaiter = node;
else
//加到链表后面
t.nextWaiter = node;
lastWaiter = node;
return node;
}
调用signal方法:
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
private void doSignal(Node first) {
//将node从等待队列转移到同步队列,node的属性也要变更
//唤醒await而挂起的线程,使其能够竞争锁
do {
if ( (firstWaiter = first.nextWaiter) == null)
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}