ReentrantLock lock = new ReentrantLock();//默認非公平鎖
lock.lock();//調用順序 NonfairSync.lock(),成功則設置線程獨佔,失敗則AbstractQueuedSynchronizer.acquire(1)[[[ 失敗就 //acquireQueued(addWaiter()),acquire這裏調用NonfairSync.tryAcquire(),tryAcquire中調用Syn.nonfairTryAcquire()]]]
lock.unlock();
//AQS.release()然後調用Syn.tryRelease()
//釋放成功則喚醒下一個節點
ReentrantLock fairlock=new ReentrantLock(true);
fairlock.lock();//調用順序 NonfairSync.lock(),直接調用AQS.acquire(1),acquire[[[中先調用FairSync.tryAcquire(1) 失敗就AQS.acquireQueued(addWaiter()) ]]]
//tryAcquire中hasQueuedPredecessors()通過判斷"當前線程"是不是在CLH隊列的隊首,來返回AQS中是不是有比“當前線程”等待更久的線程, 有等待更久的就不獲取鎖
fairlock.unlock();
public class ReentrantLock implements Lock{
private final Sync sync;//組合
abstract static class Sync extends AbstractQueuedSynchronizer {
abstract void lock();
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;
}
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;
}
}
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
/**
* 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 abstract class AbstractOwnableSynchronizer {
private transient Thread exclusiveOwnerThread;
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
protected final void getExclusiveOwnerThread {
return exclusiveOwnerThread;
}//標記是否獨佔線程
}
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer{
static final class Node {
static final Node SHARED = new Node(); /** Marker to indicate a node is waiting in shared mode */
static final Node EXCLUSIVE = null; /** Marker to indicate a node is waiting in exclusive mode */
static final int CANCELLED = 1; /**在同步隊列中等待的線程等待超時或被中斷,需要從同步隊列中取消該Node的結點即結束狀態,*進入該狀態後的結點將不會再變化*/
static final int SIGNAL = -1; /**處於喚醒狀態,只要前繼結點釋放鎖,就會通知標識爲SIGNAL狀態的後繼結點的線程執行*/
static final int CONDITION = -2; /** 該標識的結點處於等待隊列中,結點的線程等待在Condition上,當其他線程調用了Condition
的signal()方法後,CONDITION狀態的結點將從等待隊列轉移到同步隊列中,等待獲取同步鎖*/
static final int PROPAGATE = -3;// 與共享模式相關,在共享模式中,該狀態標識結點的線程處於可運行狀態
//使用在共享模式頭結點有可能處於這種狀態,表示鎖的下一次獲取可以無條件傳播
volatile int waitStatus;
volatile Node prev; volatile Node next; volatile Thread thread; Node nextWaiter;
final Node predecessor(){}; //返回該節點的前一個節點
Node() { // Used to establish initial head or SHARED marker
}
Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
}//Node類
private transient volatile Node head;
private transient volatile Node tail;
private volatile int state; // 0表示未鎖定 , 1表示鎖定
private Node enq(final Node node) { //入隊,第一個節點爲空節點,即head所指向的節點
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;
}
}
}
}
private Node addWaiter(Node mode) { //mode ShARED or EXCLUSIVE
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {//隊尾不爲空,則添加新節點到隊尾後面
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}//嘗試一次快速入隊,入隊失敗則調用enque()循環入隊
enq(node);
return node;
}
private void setHead(Node node) {//拿到資源後,將head指向該結點。所以head所指的標杆結點,就是當前獲取到資源的那個結點或null。
head = node;
node.thread = null;
node.prev = null;
}
//喚醒等待隊列中下一個線程
private void unparkSuccessor(Node node) {//這裏,node一般爲當前線程所在的結點。
int ws = node.waitStatus;
if (ws < 0)//置零當前線程所在的結點狀態,允許失敗。
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next; //找到下一個需要喚醒的結點s
if (s == null || s.waitStatus > 0) {//如果爲空或已取消
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)//從這裏可以看出,<=0的結點,都是還有效的結點。
s = t;
}
if (s != null)//喚醒
LockSupport.unpark(s.thread);
}
private void cancelAcquire(Node node) {//取消正在進行的嘗試獲取
if (node == null)// Ignore if node doesn't exist
return;
node.thread = null; //1. node不再關聯到任何線程
Node pred = node.prev;//2. 跳過被cancel的前繼node,找到一個有效的前繼節點pred
while (pred.waitStatus > 0)
node.prev = pred = pred.prev;
Node predNext = pred.next;
node.waitStatus = Node.CANCELLED;//3. 將node的waitStatus置爲CANCELLED
if (node == tail && compareAndSetTail(node, pred)) {//4. 如果node是tail,更新tail爲pred,並使pred.next指向null
compareAndSetNext(pred, predNext, null);
}
else //5. 如果node既不是tail,又不是head的後繼節點 則將node的前繼節點的waitStatus置爲SIGNAL
{ //並使node的前繼節點指向node的後繼節點(相當於將node從隊列中刪掉了)
int ws;
if (pred != head &&
((ws = pred.waitStatus) == Node.SIGNAL || (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL)))
&& pred.thread != null) {
Node next = node.next;
if (next != null && next.waitStatus <= 0)
compareAndSetNext(pred, predNext, next);
} else {//6. 如果node是head的後繼節點,則直接喚醒node的後繼節點
unparkSuccessor(node);
}
node.next = node; // help GC
}
}
final boolean acquireQueued(final Node node, int arg) {//把已經追加到隊列的線程節點(addWaiter方法返回值)進行阻塞,
boolean failed = true; //但阻塞前又通過tryAccquire重試是否能獲得鎖,如果重試成功能則無需阻塞,直接返回
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);
}
}
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {/*配合使用acquireQueued()for無限循環設置*/
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)//首先檢查前趨結點的waitStatus位,如果爲SIGNAL,表示前趨結點會通知它,那麼它可以放心大膽地掛起了
return true;
if (ws > 0) {//是一個被取消的結點向前遍歷跳過被取消的結點,直到找到一個沒有被取消的結點爲止,
do { //將找到的這個結點作爲它的前趨結點,後進入acquireQueued的無限循環
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
compareAndSetWaitStatus(pred, ws, Node.SIGNAL); //如果前繼節點狀態爲非SIGNAL、非CANCELLED,則設置前繼
} //的狀態爲SIGNAL,返回false後進入acquireQueued的無限循環
return false;//返回false表示線程不應該被掛起。
}
private final boolean parkAndCheckInterrupt() {//park and then check if interrupted
LockSupport.park(this);
return Thread.interrupted();
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //調用Sync中的tryAcquire()
selfInterrupt();
}
public final boolean release(int arg) {
if (tryRelease(arg)) {//調用Sync中的tryRealse()
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
public final boolean hasQueuedPredecessors() {//通過判斷"當前線程"是不是在CLH隊列的隊首,來返回AQS中是不是有比“當 //前線程”等待更久的線程
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());
}
}