AQS 抽象队列同步器的理解

版权声明:本文为博主原创文章,未经博主允许不得转载。http://mp.blog.csdn.net/configure#i https://blog.csdn.net/wangming520liwei/article/details/88092572

AQS(抽象的队列同步器)

ReetrantLock/CountDownLatch/Semaphore 

先看CLH 队列

static final class Node {
    /** 共享 */
    static final Node SHARED = new Node();

    /** 独占 */
    static final Node EXCLUSIVE = null;

    /**
     * 因为超时或者中断,节点会被设置为取消状态,被取消的节点时不会参与到竞争中的,他会一直保持取消状态不会转变为其他状态;
     */
    static final int CANCELLED =  1;

    /**
     * 后继节点的线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点的线程得以运行
     */
    static final int SIGNAL    = -1;

    /**
     * 节点在等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()后,改节点将会从等待队列中转移到同步队列中,加入到同步状态的获取中
     */
    static final int CONDITION = -2;

    /**
     * 表示下一次共享式同步状态获取将会无条件地传播下去
     */
    static final int PROPAGATE = -3;

    /** 等待状态 */
    volatile int waitStatus;

    /** 前驱节点 */
    volatile Node prev;

    /** 后继节点 */
    volatile Node next;

    /** 获取同步状态的线程 */
    volatile Thread thread;

    Node nextWaiter;

    final boolean isShared() {
        return nextWaiter == SHARED;
    }

    final Node predecessor() throws NullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }

    Node() {
    }

    Node(Thread thread, Node mode) {
        this.nextWaiter = mode;
        this.thread = thread;
    }

    Node(Thread thread, int waitStatus) {
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}

CANCELLED:因为超时或者中断,结点会被设置为取消状态,被取消状态的结点不应该去竞争锁,只能保持取消状态不变,不能转换为其他状态。处于这种状态的结点会被踢出队列,被GC回收;

SIGNAL:表示这个结点的继任结点被阻塞了,到时需要通知它;

CONDITION:表示这个结点在条件队列中,因为等待某个条件而被阻塞;

PROPAGATE:使用在共享模式头结点有可能牌处于这种状态,表示锁的下一次获取可以无条件传播;

0:None of the above,新结点会处于这种状态。
 

再看AQS

// arg4 当前节点的前一个节点 arg0当前节点
if (shouldParkAfterFailedAcquire(arg4, arg0)
						&& this.parkAndCheckInterrupt()) {
					arg3 = true;
				}
private final boolean parkAndCheckInterrupt() {
        // 阻塞
		LockSupport.park(this);
		return Thread.interrupted();
	}
private static boolean shouldParkAfterFailedAcquire(Node arg, Node arg0) {
        // arg是当前节点arg0的前一个节点 是不是取消状态
		int arg1 = arg.waitStatus;
		if (arg1 == -1) {
            //如果是,那么当前节点获得
			return true;
		} else {
			if (arg1 > 0) {
				do {
                    // 当前节点指向当前节点的前一个而节点的节点
					arg0.prev = arg = arg.prev;
				} while (arg.waitStatus > 0);
                // 当前节点的下一个节点是当前节点
				arg.next = arg0;
			} else {
                // 不是 -1 设置成取消状态
				compareAndSetWaitStatus(arg, arg1, -1);
			}

			return false;
		}
	}

添加CLH队列

	private Node addWaiter(Node arg0) {
        // 当前节点
		Node arg1 = new Node(Thread.currentThread(), arg0);
        // arg2尾节点
		Node arg2 = this.tail;
		if (arg2 != null) {
            // 当前节点的prev 指向尾巴节点
			arg1.prev = arg2;
            // 把当爱情呢节点设置成尾巴节点
			if (this.compareAndSetTail(arg2, arg1)) {
                // 尾节点的下一个节点是当前节点,返回当前节点
				arg2.next = arg1;
				return arg1;
			}
		}
        // 循环加入当前节点
		this.enq(arg1);
		return arg1;
	}
abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        /**
         * Performs {@link Lock#lock}. The main reason for subclassing
         * is to allow fast path for nonfair version.
         */
        abstract void lock();

        /**
         * Performs non-fair tryLock.  tryAcquire is implemented in
         * subclasses, but both need nonfair try for trylock method.
         */
        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 < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

猜你喜欢

转载自blog.csdn.net/wangming520liwei/article/details/88092572