美文网首页
AQS源码浅析(8)——Semaphore

AQS源码浅析(8)——Semaphore

作者: 墨_0b54 | 来源:发表于2022-04-27 19:57 被阅读0次
    • Semaphore(信号量)属于共享锁的一种实现,可以指定多个线程同时访问某个资源
    • Semaphore 维持了一个可获得许可证的数量,经常用于限制获取某种资源的线程数量
    • Semaphore 有两种模式,公平模式和非公平模式
    public Semaphore(int permits) {//permits是许可数量,默认非公平模式
        sync = new NonfairSync(permits);
    }
    public Semaphore(int permits, boolean fair) {//fair为true时是公平模式
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }
    
    • acquire 获取许可证,可能阻塞直到有足够的许可证
    • release 增加许可证,这可能会释放一个阻塞的 acquire
    semaphore.acquire(5);// 获取5个许可
    test(threadnum);
    semaphore.release(5);// 释放5个许可
    
    • Semaphore将state视作许可证数量,看看源码实现
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1192457210091910933L;
        Sync(int permits) {
            setState(permits);
        }
        final int getPermits() {
            return getState();
        }
        final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 || //有足够的许可
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }
        protected final boolean tryReleaseShared(int releases) {
            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;
            }
        }
        final void reducePermits(int reductions) {//减少许可
            for (;;) {
                int current = getState();
                int next = current - reductions;
                if (next > current) // underflow
                    throw new Error("Permit count underflow");
                if (compareAndSetState(current, next))
                    return;
            }
        }
        final int drainPermits() {//获取并返回立即可用的所有许可个数,并且将可用许可置0
            for (;;) {
                int current = getState();
                if (current == 0 || compareAndSetState(current, 0))
                    return current;
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:AQS源码浅析(8)——Semaphore

          本文链接:https://www.haomeiwen.com/subject/zuqssrtx.html