我們先來看一下這個併發框架的原理,在之後的文章中我們將乙個乙個的分析那些有用的實現。
public final void acquire(int arg)
這個方法是獲取到資源的入口,首先他會嘗試來獲取arg個資源,如果沒有獲取成功,就會呼叫後面的方法將這次請求放到乙個同步佇列裡面,如果都失敗了,就會呼叫當前請求資源的中斷方法:
protected boolean tryacquire(int arg)
這個方法是讓具體的場景來實現的,我們接下來看一下如何新增到同步佇列當中:
addwaiter(node.exclusive)
首先建立了乙個waiter,裡面傳入了乙個引數:
static final node shared = new node();
//表示節點正在排它模式下等待的標記
static final node exclusive = null;
//等待狀態值,指示執行緒已取消
static final int cancelled = 1;
//等待狀態值,以指示後續執行緒需要解除安裝
static final int signal = -1;
//waitstatus值表示執行緒正在等待條件
static final int condition = -2;
//*等待狀態值,以指示下乙個獲取共享應該無條件地傳播
static final int propagate = -3;
我們建立的沒有給結點都有乙個他自己的狀態:
private node addwaiter(node mode)
}//入隊
enq(node);
return node;
}
這個方法首先會根據請求資源的執行緒和模式建立要給同步結點,然後先建立他的前指標和尾節點的關係,這羊座的原因是,就算在入隊的時候失敗了,也可以通過同步佇列的尾節點遍歷整個同步佇列,最後一步就是入隊:
private node enq(final node node) else }}
}
在這個方法中,首先獲取到了尾節點進行判斷這是否是新增的第乙個結點,如果是,直接通過cas操作將當前結點設定為頭節點,否則將當前結點通過cas操作設定為尾節點。這樣新的結點也入隊成功了,接下來他就帶著他需要請求的資源的個數進入下乙個方法:
final boolean acquirequeued(final node node, int arg)
//檢查和更新未能獲取的節點的狀態。如果執行緒阻塞,返回true
if (shouldparkafte***iledacquire(p, node) &&
//檢查是否中斷
parkandcheckinterrupt())
//標記當前執行緒被中斷
interrupted = true;
}} finally
}
首先通過自旋的方式檢查它的前結點是否是頭節點,如果是,讓他的前結點嘗試獲取資源,如果成功將當前結點設定為頭節點,並且返回。之後會根據前驅結點不同的狀態來做不同的處理是否需要掛起,如果需要掛起,那麼接下來就會先掛起當前執行緒,再檢查當前執行緒是否中斷:
private static boolean shouldparkafte***iledacquire(node pred, node node) while (pred.waitstatus > 0);
pred.next = node;
} else
return false;
}
這個方法主要就是根據前驅結點不同的狀態值來做不同的處理。
private final boolean parkandcheckinterrupt()
這個方法就是掛起當前執行緒並判斷是否被中斷
private void cancelacquire(node node) else else
node.next = node; // help gc
}}
刪除這個結點重新建立鍊錶之間的關係,再必要條件下喚醒它的繼承者:
private void unparksuccessor(node node)
//喚醒當前執行緒
if (s != null)
locksupport.unpark(s.thread);
}
從當前結點開始找到第乙個狀態不為0的結點喚醒它。
接下來我們看一下符合釋放資源:
public void unlock()
直接呼叫的是同步框架的釋放方法,傳入的是釋放的資源的個數:
public final boolean release(int arg)
return false;
}
首先會嘗試釋放資源,成功後會喚醒同步佇列中頭節點的繼承者:
protected boolean tryrelease(int arg)
釋放資源也是由具體的場景完成的:
private void unparksuccessor(node node)
if (s != null)
locksupport.unpark(s.thread);
}
這個方法和之前的我們分析的方法是一樣的,我們就不具體看了。
再本章中我們只分析了一些主要的功能和一般流程,在後面的部落格中我們就要看具體的案例了。
AQS框架 談談對AQS框架的理解
aqs是乙個框架,基於它我們可以實現鎖和同步器,j.u.c.包中和很多鎖和同步器都是基於aqs實現的。使用aqs的方式通常不是讓鎖或同步器直接繼承aqs類,而是將aqs的子類作為鎖或同步器類的乙個輔助內部類,鎖或同步器的方法呼叫aqs子類物件的方法完成同步操作。來自網路 aqs中最重要的乙個字段就是...
spring mvc框架及基本流程
原創 傳統原生的jsp servlet在開發上過程上雖然簡單明瞭,jsp頁面傳遞資料到servlet,servlet整理資料 邏輯開發 或者從資料庫提取資料接著再 到jsp頁面上,但是其似乎只能止步於此,我們都知道我們request和response都依賴於url,當我們想要通過針對圍繞url進行程...
AQS框架實現類學習
author jinxindong 2016年11月1日 上午9 33 46 version v1.0 public class countdownlatchdemo static class worker extends thread public void run catch interrupt...