java併發程式設計的藝術(六) AQS

2021-08-08 19:33:39 字數 2240 閱讀 9165

aqs是佇列同步器(abstractqueuesynchronizer),是用來構建鎖和完成其他同步元件的基本框架,再lock裡面,很多的方法都將用到aqs以獲取同步狀態,實現鎖的語義,而不是依靠傳統的synchronized中的物件進行鎖獲取與釋放。

aqs的核心思想是基於volatile int state這樣的乙個屬性同時配合unsafe工具對其原子性的操作來實現對當前鎖的狀態進行修改。當state的值為0的時候,標識改lock不被任何執行緒所占有

「羊群效應」指的是很多的執行緒在競爭同乙個資源或鎖的時候,最後只能由乙個執行緒獲得鎖,這個獲取資源或鎖的過程中,就會造成資源的浪費。

aqs採用乙個fifo的同步佇列的資料結構,每個節點只需要關心上乙個前驅節點的狀態,執行緒喚醒也只喚醒頭節點中等待的執行緒。與其讓這些執行緒相互競爭,還不如它們安排好順序乙個乙個來。

之前說的,aqs是採用的一中fifo佇列的資料結構,同步佇列的指標裡面包含指向頭節點和偽結點的指標。而每個節點都是用來儲存競爭執行緒的狀態和資訊的,節點的主要成員變數如下:

node
獨佔式同步狀態的獲取原始碼分析

//通過acquire方法獲取同步狀態,裡面呼叫由子類實現的tryacquire方法

//若獲取失敗就將該執行緒加入同步佇列中繼續自旋獲取同步狀態

public

final

void

acquire(int arg)

//將當前執行緒的資訊構造成節點加入同步佇列中

//**執行過程大致就是將當前執行緒生成的新節點加入同步佇列的尾節點

//但需要運用compareandsettail來確保節點能夠被執行緒安全的新增

//因為用普通鍊錶提供的方法來修改,在多執行緒的併發情況下不能保證節點新增的順序性

private node addwaiter(node mode)

}enq(node);

return node;

}//通過enq這個方法,以一種死迴圈的方式來保證節點的正確新增,並且是採用cas操作成功後,enq方法才返回

private node enq(final node node) else }}

}//新增新節點到同步節點後,acquirequeued方法就是通過自旋來獲取同步狀態,

//就相當於自旋來競爭鎖資源了

final

boolean acquirequeued(final node node, int arg)

if (shouldparkafte***iledacquire(p, node) &&

parkandcheckinterrupt())

interrupted = true;

}} finally

}

獨佔式同步狀態釋放的原始碼分析:

public

final

boolean

release(int arg)

return

false;

}

獨佔式超時獲取同步狀態就是在獨佔式獲取同步狀態上面新增超時方法返回處理,不必非得等到獲取同步狀態方法才返回。在原始碼上面,大致就是acquirequeued和doacquirenanos的實現過程有差異,在doacquirenanos裡面新增了超時判斷和處理**

原始碼如下:

private

boolean

doacquirenanos(int arg, long nanostimeout)

throws interruptedexception

nanostimeout = deadline - system.nanotime();

if (nanostimeout <= 0l)

return

false;

if (shouldparkafte***iledacquire(p, node) &&

nanostimeout > spinfortimeoutthreshold)

locksupport.parknanos(this, nanostimeout);

if (thread.interrupted())

throw

new interruptedexception();

}} finally

}

Java併發程式設計的藝術 筆記

併發存在的問題 上下文切換耗時,死鎖,軟硬體資源限制 解決方法 減少上下文切換 1.無鎖併發程式設計 讓不同的執行緒處理不同的資料段 將資料id採用hash演算法分配給不同的執行緒 2.cas演算法 compare and set使用jni 3.使用最少執行緒 減少處於waiting狀態的執行緒 j...

java併發程式設計 六

併發工具類 lk最近學習了併發工具類的知識,總結一下它們的用法 1.countdownlatch 2.cyclicbarrier 3.semaphore 4.exchanger 使用完countdownlatch之後,覺得它適合應用於讓其它執行緒去各自執行完,然後main執行緒開始執行的場合 自己理...

Java併發程式設計的藝術 筆記2

現代作業系統排程的最小單位是執行緒,也叫輕量級程序,每個程序可建立多個程序,每個執行緒都有各自的計數器 堆疊和區域性變數等屬性,並且能夠訪問共享變數。處理器在這些執行緒上高速切換,讓使用者感覺到這些執行緒在同時執行。執行緒優先順序 決定執行緒分配處理器資源多少的屬性,設定時,針對頻繁阻塞 休眠或i ...