您的位置:首頁>正文

ReentrantLock 源碼分析

ReentrantLock是比較常用一種鎖, 下面通過對ReentrantLock鎖對非公平實現進行源碼分析, 通過源碼分析對其進行深入的理解, 主要基於下圖的過程進行分析。

獲取鎖的過程

首先在ReentrantLocl.NonfairSync.lock方法中首先是嘗試通過調用父類方法進行CAS方式獲取鎖, 如果獲取

鎖成功後則將排它鎖持有執行緒設置為當前執行緒。 如果沒有獲取到鎖則調用AQS方法獲取鎖。

final void lock { //首先直接嘗試獲取鎖, 如果獲取鎖成功, 則將持有鎖的執行緒設置為當前執行緒, 否則調用父類的acquire(1)方法獲取鎖資源 if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread); else acquire(1); }

在AQS方法中是如何獲取鎖的呢?

//獨佔模式獲取資源, 在獲取到資源的過程中中斷過, 則在獲取資源後會在此自我中斷 public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt; }

tryAcquire延遲到了子類方法, 也就是ReentrantLocl.NonFairSync

protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); }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

acquireQueued是AQS方法

final boolean acquireQueued(final Node node, int arg) { //標記獲取資源失敗, 預設為true boolean failed = true; try { //標記等待過程中是否被中斷過 boolean interrupted = false; //自旋 for (;;) { //獲取當前節點的前驅 final Node p = node.predecessor; //如果前驅是佇列頭則嘗試獲取資源 if (p == head && tryAcquire(arg)) { //拿到資源以後就將head節點指向當前節點,
故head節點就表示當前持有資源的節點 setHead(node); //將前驅節點的後繼設置為null,表示這個節點從佇列中刪除, 在GC的時候可以被回收 p.next = null; //已經成功獲取資源了, 則將failed標記設置為false; failed = false; //返回是否中斷過 return interrupted; } // if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt) //如果等待過程被中斷過就標記為true interrupted = true; } } finally { //如果自旋後還是失敗則取消獲取資源 if (failed) cancelAcquire(node); } } /** *中斷當前執行緒 */ static void selfInterrupt { Thread.currentThread.interrupt; }
同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示