Semaphore共享锁解析

Tell me how can I go on without somebody to love

首先看Semaphore的构造方法

public Semaphore(int permits) {
    sync = new NonfairSync(permits);
}

java.util.concurrent.Semaphore.NonfairSync#NonfairSync

NonfairSync(int permits) {
    super(permits);
}

java.util.concurrent.Semaphore.Sync#Sync

Sync(int permits) {
    setState(permits);
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#setState

protected final void setState(int newState) {
    state = newState;
}

即一开始就将资源数设置到state中

调用acquire方法获取资源

java.util.concurrent.Semaphore#acquire()

public void acquire() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#acquireSharedInterruptibly

public final void acquireSharedInterruptibly(int arg)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    // 尝试获取资源
    if (tryAcquireShared(arg) < 0)
        doAcquireSharedInterruptibly(arg); // 获取资源失败
}

java.util.concurrent.Semaphore.NonfairSync#tryAcquireShared

protected int tryAcquireShared(int acquires) {
    return nonfairTryAcquireShared(acquires);
}

java.util.concurrent.Semaphore.Sync#nonfairTryAcquireShared

final int nonfairTryAcquireShared(int acquires) {
	// 使用死循环多次尝试
    for (;;) {
    	// 获取state即资源数
        int available = getState();
        int remaining = available - acquires;
        // 如果资源不足或使用cas获取资源成功,返回最新的资源数
        if (remaining < 0 ||
            compareAndSetState(available, remaining))
            return remaining;
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#doAcquireSharedInterruptibly

private void doAcquireSharedInterruptibly(int arg)
    throws InterruptedException {
    // 添加一个共享状态的节点(addWaiter方法在上篇ReetrantLock里有解析)
    final Node node = addWaiter(Node.SHARED);
    boolean failed = true;
    try {
        for (;;) { // 死循环多次尝试
        	// 拿到新节点的前驱节点
            final Node p = node.predecessor();
            if (p == head) { // 如果是head节点
                int r = tryAcquireShared(arg); // 再去尝试获取资源
                if (r >= 0) {
                    setHeadAndPropagate(node, r);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
            }
            // 查看前驱节点是否可唤醒(注意这里是在死循环里的,所以会循环进行前驱节点的健康检测,知道满足条件为止)  并 阻塞线程
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                throw new InterruptedException();
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#shouldParkAfterFailedAcquire

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    int ws = pred.waitStatus;
    if (ws == Node.SIGNAL) // 如果前驱状态是可以被唤醒的,返回true
        return true;
    if (ws > 0) { // 如果前驱节点已经被废除,将前驱指向前驱的前驱,并将前驱的前驱的后继指向当前节点
        do {
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else { // 使用cas算法设置前驱节点为可唤醒状态
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
    }
    return false;
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#parkAndCheckInterrupt
// 阻塞线程
private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);
    return Thread.interrupted();
}

调用release方法返回资源

public void release() {
    sync.releaseShared(1);
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#releaseShared

public final boolean releaseShared(int arg) {
	// 尝试释放资源
    if (tryReleaseShared(arg)) {
    	// 释放资源后续操作
        doReleaseShared();
        return true;
    }
    return false;
}

java.util.concurrent.Semaphore.Sync#tryReleaseShared

protected final boolean tryReleaseShared(int releases) {
	// 死循环多次尝试,将释放资源数加到state里,以cas算法设置回去
    for (;;) {
        int current = getState();
        int next = current + releases;
        if (next < current) // overflow
            throw new Error("Maximum permit count exceeded");
        if (compareAndSetState(current, next))
            return true;
    }
}

java.util.concurrent.locks.AbstractQueuedSynchronizer#doReleaseShared

private void doReleaseShared() {
    for (;;) { // 死循环多次尝试
        Node h = head;
        if (h != null && h != tail) {
            int ws = h.waitStatus;
            if (ws == Node.SIGNAL) { // 如果头结点是Signal状态
            	// 设置头结点状态为0
                if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
                    continue;           
                // 设置成功后unpark进行唤醒
                unparkSuccessor(h);
            }
            // 如果头节点是重置状态0,则设置为广播状态
            else if (ws == 0 &&
                     !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                continue;
        }
        if (h == head)
            break;
    }
}

CountDownLatch和CyclicBarrier、Exchanger这三个组件同理,不再进行解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值