Skip to content

Instantly share code, notes, and snippets.

View tshy0931's full-sized avatar

tshy0931

  • Dublin
View GitHub Profile
@tshy0931
tshy0931 / acquire_and_addWriter.java
Created December 11, 2018 16:46
AQS source code - acquire in exclusive mode, and add thread(Node) to waiting list
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
//尝试获取锁,失败则为当前线程创建节点并入队等待。arg也会被保存在节点内
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //等待排他权限
selfInterrupt(); //1. 不清楚这里为什么要中断一下当前线程?
}
// 为当前线程创建排他/共享模式的节点并加入节点队列
private Node addWaiter(Node mode) {
// 为当前线程创建一个Node实例
@tshy0931
tshy0931 / enq.java
Created December 11, 2018 16:48
AQS source code - enqueue a Node
private Node enq(final Node node) {
for (;;) { //若CAS失败则反复重试,直到CAS成功后才返回
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node())) //CAS初始化头节点
tail = head;
} else {
//连接前驱节点
node.prev = t;
if (compareAndSetTail(t, node)){ //CAS更新尾节点为新插入节点
@tshy0931
tshy0931 / acquireQueued.java
Created December 11, 2018 16:52
AQS source code - check whether should park a thread after failed acquire
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
// 获取当前线程对应节点的前驱节点
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
// 当前节点位于队首,则重新尝试获取锁,
// 获取锁成功则将本节点出队并设为head
@tshy0931
tshy0931 / shouldParkAfterFailedAcquire.java
Created December 11, 2018 16:54
AQS source code - check if thread can park, and skip cancelled nodes
/**
* Checks and updates status for a node that failed to acquire.
* Returns true if thread should block. This is the main signal
* control in all acquire loops. Requires that pred == node.prev.
*
* @param pred node's predecessor holding status
* @param node the node
* @return {@code true} if thread should block
*/
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
@tshy0931
tshy0931 / cancelAcquire.java
Created December 11, 2018 16:55
AQS source code - cancel an acquire and clean up the node
private void cancelAcquire(Node node) {
// Ignore if node doesn't exist
if (node == null)
return;
node.thread = null; // 清理节点中线程的引用
// Skip cancelled predecessors
// 跳过前方已取消的节点
Node pred = node.prev;
@tshy0931
tshy0931 / unparkSuccessor.java
Created December 11, 2018 16:58
AQS source code - unpark the successor node if exists, otherwise unpark the first non-cancel node in the queue
private void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
@tshy0931
tshy0931 / doAcquireShared.java
Created December 11, 2018 16:59
AQS source code - acquire shared lock, park thread or retry if failed
private void doAcquireShared(int arg) {
final Node node = addWaiter(Node.SHARED); // 创建共享模式的Node节点
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor(); // 获取前驱节点
if (p == head) {
// 尝试获取共享锁,失败则返回负值,成功时返回的正值表示剩余可用的共享锁数量
int r = tryAcquireShared(arg);
@tshy0931
tshy0931 / setHeadAndPropagate.java
Created December 11, 2018 17:04
AQS source code - set the node as head, and propagate release to the queue
/**
* 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) {
Node h = head; // Record old head for check below
@tshy0931
tshy0931 / doReleaseShared.java
Created December 11, 2018 17:08
AQS source code - unpark head node's successor node, or set PROPAGATE to head node
/**
* Release action for shared mode -- signals successor and ensures
* propagation. (Note: For exclusive mode, release just amounts
* to calling unparkSuccessor of head if it needs signal.)
*/
private void doReleaseShared() {
/*
* Ensure that a release propagates, even if there are other
* in-progress acquires/releases. This proceeds in the usual
* way of trying to unparkSuccessor of head if it needs
@tshy0931
tshy0931 / nonfairTryAcquire.java
Last active December 11, 2018 17:51
ReentrantLock - acquire log in an unfair manner
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) { // 0 表示锁可用
if (compareAndSetState(0, acquires)) { // CAS获取相应数量的锁
setExclusiveOwnerThread(current); // 记录当前线程为占用排他锁的线程,用以让该线程可以重入地再次获取
return true;
}
}
else if (current == getExclusiveOwnerThread()) { // 允许占有排他锁的线程重入