變量解釋:
public abstract class AbstractOwnableSynchronizer
implements java.io.Serializable {
...
/** * The current owner of exclusive mode synchronization. * 持有該鎖的目前線程 */
private transient Thread exclusiveOwnerThread;
...
}
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
...
/**
* The synchronization state.
* 0: 初始狀态-無任何線程得到了鎖
* > 0: 被線程持有, 具體值表示被目前線程持有的執行次數
*
* 這個字段在解鎖的時候也需要用到。
* 注意這個字段的修飾詞: volatile
*/
private volatile int state;
...
}
公平鎖FairSync:
/**
* Sync object for fair locks
*/
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
// AQS的acquire方法。獨占方式。嘗試擷取資源,成功則傳回true,失敗則傳回false。
acquire(1);
}
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
* (翻譯:tryAcquiere的公平鎖實作版本,除非有遞歸、沒有等待者、或者有優先,否則不要授予鎖權限)
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
// AQS使用一個int類型的成員變量state來表示同步狀态,當state = 1時表示已經擷取了鎖,當state = 0時表示釋放了鎖。
// getState():傳回同步狀态的目前值;
int c = getState();
if (c == 0) { // 如果目前線程沒有擷取過鎖,則嘗試加鎖
//與非公平鎖不同的是,此處多了hasQueuedPredecessors()判斷,該方法是實作公平鎖的關鍵。
//如果hasQueuedPredecessors傳回true,表示有其他線程先于目前線程等待擷取鎖,此時為了實作公平,保證等待時間最長的線程先擷取到鎖,不能執行CAS。
//protected final boolean compareandsetstate(int expect, int update)
//如果目前狀态值等于預期值,則以原子方式将同步狀态設定為給定的更新值。此操作具有 volatile 讀和寫的記憶體語義。
//參數:expect - 預期值 update - 新值
//傳回:如果成功,則傳回 true。傳回 false 訓示實際值與預期值不相等。
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
// 設定占用排它鎖的線程是目前線程
setExclusiveOwnerThread(current);
return true;
}
}
// getExclusiveOwnerThread(): 傳回由 setexclusiveownerthread 最後設定的線程;如果從未設定,則傳回 null。此方法不另外施加任何同步或 volatile 字段通路。
else if (current == getExclusiveOwnerThread()) { //目前線程已經擷取到鎖,重入
int nextc = c + acquires; // 鎖狀态計數器累加
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
非公平鎖NonfairSync:
/**
* Sync object for non-fair locks
*/
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);
}
}
FairSync: