共享鎖的乙個實現類就是訊號量semaphore,semaphores一般用於對某種訪問資源的限制,乙個訊號量相當於持有一些許可(permits),執行緒可以呼叫semaphore物件的acquire()方法獲取乙個許可,呼叫release()來歸還乙個許可。
同樣semaphore有公平和非公平兩種模式。預設就是非公平模式。
先看下aqs的acquireshared()方法
/**
* acquires in shared mode, ignoring interrupts. implemented by
* first invoking at least once ,
* returning on success. otherwise the thread is queued, possibly
* repeatedly blocking and unblocking, invoking until success.
** @param arg the acquire argument. this value is conveyed to
* but is otherwise uninterpreted
* and can represent anything you like.
*/public final void acquireshared(int arg)
/**
* acquires in shared uninterruptible mode.
* @param arg the acquire argument
*/private void doacquireshared(int arg)
}// 判斷狀態,尋找安全點,進入waiting狀態,等著被unpark()或interrupt()
if (shouldparkafte***iledacquire(p, node) &&
parkandcheckinterrupt())
interrupted = true;
}} finally
}
/**
* sets head of queue, and checks if successor may be waiting
* in shared mode, if so propagating if either propagate > 0 or
* propagate status was set.
** @param node the node
* @param propagate the return value from a tryacquireshared
*/private void setheadandpropagate(node node, int propagate)
}
acquire()總結
tryacquireshared()嘗試獲取資源,成功則直接返回,否則進入流程2。
doacquireshared()會將當前執行緒加入等待佇列尾部休息,直到其他執行緒釋放資源喚醒自己。它還會嘗試著讓喚醒傳遞到後面的節點。
其實跟acquire()的流程大同小異,只不過多了個自己拿到資源後,還會去喚醒後繼隊友的操作(這才是共享嘛)。
接下來看下releaseshared()
/**
* releases in shared mode. implemented by unblocking one or more
* threads if returns true.
** @param arg the release argument. this value is conveyed to
* but is otherwise uninterpreted
* and can represent anything you like.
* @return the value returned from
*/public final boolean releaseshared(int arg)
return false;
}
/**
* release action for shared mode -- signal successor and ensure
* propagation. (note: for exclusive mode, release just amounts
* to calling unparksuccessor of head if it needs signal.)
*/private void doreleaseshared()
//如果後繼節點暫時不需要喚醒,則把當前節點狀態設定為propagate確保以後可以傳遞下去
else if (ws == 0 &&
!compareandsetwaitstatus(h, 0, node.propagate))
continue;
}//如果頭結點沒有發生變化,表示設定完成,退出迴圈
//如果頭結點發生變化,比如說其他執行緒獲取到了鎖,為了使自己的喚醒動作可以傳遞,必須進行重試
if (h == head)
break;
}}
到這裡,aqs的解讀先告一段落。 Java併發之AQS原理詳解
一 abstractqueuedsynchronizer 的用途 下面簡稱 aqs,jdk 1.8 aqs是借助 fifo等待佇列,用來實現同步器的同步框架,通俗的來說,它是用來實現鎖的工具,一般來說,它需要實現這些功能 二 aqs 的工作原理 aqs的核心是基於鍊錶實現的 fifo等待佇列,該佇列...
AQS之countDownLatch原始碼解析
public class countdownlatch int getcount protected int tryacquireshared int acquires protected boolean tryreleaseshared int releases private final syn...
AQS 同步佇列共享模式
首先來看看acquireshared public final void acquireshared int arg tryacquireshared 方法同樣由自定義同步器實現,用來給state原子的加一些操作。如果tryacquireshared 0說明當前執行緒嘗試獲取資源失敗需要進入同步佇列...