Semaphore源码

java.util.concurrent.Semaphore implements java.io.Serializable

Semaphore类称为信号量,本质上是一个共享锁。维持一定数量的许可,当线程通过acquire请求许可时,若已超过指定数量,则必须等待。

1.类变量&常量

    private final Sync sync; //提供所有实现机制的同步器

2.构造方法

    //输入参数表示许可数,默认为非公平锁
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

    //通过fair参数可选择公平锁或非公平锁
    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

3.重要方法

1.acquire方法,线程获取许可,若有可用许可则可正常获得,否则一直等待直到有可用许可。
    //默认无参数acquire方法,获取一个许可,可中断
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    //获取permits个许可,一次性获得
    public void acquire(int permits) throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireSharedInterruptibly(permits);
    }

    //获取一个许可,不可中断
    public void acquireUninterruptibly() {
        sync.acquireShared(1);
    }

    //获取permits个许可,不可中断
    public void acquireUninterruptibly(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireShared(permits);
    }
2.tryAcquire方法,试图获取permit,否则将直接返回false   
    public boolean tryAcquire() {
        return sync.nonfairTryAcquireShared(1) >= 0;
    }

    public boolean tryAcquire(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.nonfairTryAcquireShared(permits) >= 0;
    }

    //有等待时间的试图获取permits个permit
    public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
        throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
    }

    //有等待时间的试图获取1个permit
    public boolean tryAcquire(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }    
3.  availablePermits方法,获取总共可用数
    public int availablePermits() {
        return sync.getPermits();
    }
4.  drainPermits方法,acquire全部可用的permit
    public int drainPermits() {
        return sync.drainPermits();
    }
5.  getQueuedThreads方法,获取当前等待许可的全部线程,返回一个容器类
    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }
6.  getQueueLength方法,获取等待队列的长度 
    public final int getQueueLength() {
        return sync.getQueueLength();
    }
7.  hasQueuedThreads方法,是否有等待的线程  
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }
8.reducePermits方法,减少许可数
    protected void reducePermits(int reduction) {
        if (reduction < 0) throw new IllegalArgumentException();
        sync.reducePermits(reduction);
    }
9.release方法,线程不再需要许可时,即调用该方法

    //释放1个许可
    public void release() {
        sync.releaseShared(1);
    }

    //释放permits个许可
    public void release(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.releaseShared(permits);
    }    

4.内部类

1.Sync类,实现Senaphore类核心功能的父类,继承自AQS类

1.1 构造方法
    //将标识为设置成许可数
    Sync(int permits) {
        setState(permits);
    }

1.2 getPermits方法,获取标志位
    final int getPermits() {
        return getState();
    }

1.3 nonfairTryAcquireShared方法,每有1次acquire方法调用,就调用一次该方法,
将标志位减去请求许可数。若remaining小于0,则返回负值,从而线程等待
    final int nonfairTryAcquireShared(int acquires) {
        for (;;) {
            int available = getState();
            int remaining = available - acquires;
            if (remaining < 0 ||
                compareAndSetState(available, remaining))
                return remaining;
        }
    }

1.4 tryReleaseShared方法,每有一次调用release方法,就调用一次该方法。将标识位加上所要释放的许可数。      
    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;
        }
    }

1.5 reducePermits方法,减少reducitons个许可        
    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;
        }
    }

1.6 drainPermits方法,一次性获取全部permit
    final int drainPermits() {
        for (;;) {
            int current = getState();
            if (current == 0 || compareAndSetState(current, 0))
                return current;
        }
    }
2.FairSync类,实现公平锁,继承自Sync类
2.1 构造方法
    FairSync(int permits) {
        super(permits);
    }

2.2 tryAcquireShared方法,获取acquires个许可
    protected int tryAcquireShared(int acquires) {
        for (;;) {
            if (hasQueuedPredecessors())    //判断当前线程是不是sync队列的第一个线程,若不是则返回-1
                return -1;
            int available = getState();
            int remaining = available - acquires;   //减少可用许可数
            //若剩余许可》=0,则将标志位设置成剩余许可
            if (remaining < 0 ||
                compareAndSetState(available, remaining))
                return remaining;
        }
    }
3.NonfairSync,实现非公平锁,继承自Sync类
2.1 构造方法
    NonfairSync(int permits) {
        super(permits);
    }

2.2 tryAcquireShared方法,获取acquires个许可
    protected int tryAcquireShared(int acquires) {
        return nonfairTryAcquireShared(acquires); //以非公平锁的形式获取,调用父类方法
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值