Semaphore源码解析

Semaphore的实现主要依赖AbstractQueuedSynchronized,它实现了AQS的共享锁方案,即实现了tryAcquireShared与tryReleaseShared这两个方法。

  1. Sync,继承自AbstractQueuedSynchronized,实现了非公平的tryAcquireShared方法与tryReleaseShared。

    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1192457210091910933L;
    
        // 这是与排它锁的区别,排它锁的state默认为1.
        // 而共享锁的state可以自己设定,如果state<=0,那必须要执行一次tryReleaseShared
        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 || // 如果remaining<0,是不会执行compareAndSetState(available, remaining)的
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }
    
        /**
         * 非公平模式与公平模式,对于锁的释放是一样的
         */
        protected final boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (next < current)
                    throw new Error("Maximum permit count exceeded");
                if (compareAndSetState(current, next))
                    return true;
            }
        }
    
        /**
         * 这个方法与tryReleaseShared的实现几乎一模一样,除了返回类型,用来减少Permits
         */
        final void reducePermits(int reductions) {
            for (;;) {
                int current = getState();
                int next = current - reductions;
                if (next > current)
                    throw new Error("Permit count underflow");
                if (compareAndSetState(current, next))
                    return;
            }
        }
    
        /**
         * 将state设置为0
         */
        final int drainPermits() {
            for (;;) {
                int current = getState();
                if (current == 0 || compareAndSetState(current, 0))
                    return current;
            }
        }
    }
  2. NonfairSync,非公平策略,与ReentrantLock一样,直接使用Sync提供的方式。

    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = -2694183684443567898L;
    
        NonfairSync(int permits) {
            super(permits);
        }
    
        protected int tryAcquireShared(int acquires) {
            return nonfairTryAcquireShared(acquires);
        }
    }
  3. FairSync,公平策略,重写了tryAcquireShared

    static final class FairSync extends Sync {
        private static final long serialVersionUID = 2014338818796000944L;
    
        FairSync(int permits) {
            super(permits);
        }
    
        // 与非公平的区别就在这里
        protected int tryAcquireShared(int acquires) {
            for (;;) {
                // 如果当前线程不是队列的head,这不竞争
                // 如果当前线程是队列的head,hasQueuedPredecessors返回false
                if (hasQueuedPredecessors())
                    return -1;
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值