java簡單AQS使用

AQS是一種併發數據結構,node

  1. volatile int state
  2. blockingQueue工做隊列
  3. lockOwner鎖的全部者

以公平鎖的acquire爲例分析相關代碼數據結構

public final void acquire(int i){
	if(!tryAcquired()&&
		acquireQueued(addWaiter(Node.EXCLUSIVE),arg)){
		selfInterrrupt();
	}

}

tryAcquire()-以ReentrantLock的fairTryAcquire(int acquire)爲例

獲取當前state
if(state==0){
  無人佔用,則經過cas改變state狀態,
  成功後,從新設置鎖的全部者;
  return true;
}else{
  if(當前線程=鎖的全部者){
     state+=1;設置state;
	 return true;
  }
  return false;
}

acquireQueued方法

final boolean acquireQueued(final Node node, int arg) {
      boolean interrupted = false;
      try {
    	for (;;) {// 循環
        	final Node p = node.predecessor();// 獲取前一個節點
        	if (p == head && tryAcquire(arg)) { // 若是前一個節點是頭結點,表示當前節點合適去 tryAcquire
            	setHead(node); // acquire 成功,則設置新的頭節點
            	p.next = null; // 將前面節點對當前節點的引用清空
            	return interrupted;
        	}
        	if (shouldParkAfterFailedAcquire(p, node)) // 檢查是否失敗後須要 park
            	interrupted |= parkAndCheckInterrupt();
    	}
       } catch (Throwable t) {
    	cancelAcquire(node);// 出現異常,取消
    	if (interrupted)
        	    selfInterrupt();
    	throw t;
      }
}
  • 循環判斷,主要是當本節點成爲表頭的下一個元素時,去搶佔鎖,若是成功,則返回結果,中止循環;
  • 獲取鎖不成功,就查看隊列是否已滿/已取消.須要不須要中斷獲取鎖的線程;
  • 捕獲異常,判斷,若是interrupted爲true,中斷線程
相關文章
相關標籤/搜索