J.U.C之AQS-Semaphore

https://mp.weixin.qq.com/s/jTRpP66tL8l49XRUWDtnYQ
之前介绍的锁都是限制只有一个线程可以同时访问一个资源。
现实中,资源往往有多个,但每个同时只能被一个线程访问,比如,饭店的饭桌、火车上的卫生间。
有的单个资源即使可以被并发访问,但并发访问数多了可能影响性能,所以希望限制并发访问的线程数。
还有的情况,与软件的授权和计费有关,对不同等级的账户,限制不同的最大并发访问数。

信号量类Semaphore就是用来解决这类问题的,它可以限制对资源的并发访问数,它有两个构造方法:

public Semaphore(int permits)

public Semaphore(int permits, boolean fair)

fire表示公平,含义与之前介绍的是类似的,permits表示许可数量。

Semaphore的方法与锁是类似的,主要的方法有两类,获取许可和释放许可,主要方法有:

//阻塞获取许可

public void acquire() throws InterruptedException

//阻塞获取许可,不响应中断

public void acquireUninterruptibly()

//批量获取多个许可

public void acquire(int permits) throws InterruptedException

public void acquireUninterruptibly(int permits)

//尝试获取

public boolean tryAcquire()

//限定等待时间获取

public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException

//释放许可

public void release()

我们看个简单的示例,限制并发访问的用户数不超过100,代码如下:

public class AccessControlService {
    
    //自定义异常
    public static class ConcurrentLimitException extends RuntimeException {
        
        private static final long serialVersionUID = 1L;
    }

    //限制100个
    private static final int MAX_PERMITS = 100;
    private Semaphore permits = new Semaphore(MAX_PERMITS, true);

    public boolean login(String name, String password) {
        if (!permits.tryAcquire()) {
            // 同时登录用户数超过限制
            throw new ConcurrentLimitException();
        }
        // ..其他验证
        return true;
    }

    //释放一个
    public void logout(String name) {
        permits.release();
    }

}

需要说明的是,如果我们将permits的值设为1,你可能会认为它就变成了一般的锁,不过,它与一般的锁是不同的。一般锁只能由持有锁的线程释放,
而Semaphore表示的只是一个许可数,任意线程都可以调用其release方法。
主要的锁实现类ReentrantLock是可重入的,而Semaphore不是,每一次的acquire调用,即使是已经得到许可的,都会消耗一个许可,比如,看下面代码段:

Semaphore permits = new Semaphore(1);
permits.acquire();
permits.acquire();
System.out.println("acquired");

程序会阻塞在第二个acquire调用,永远都不会输出"acquired"。

信号量的基本原理比较简单,也是基于AQS实现的,permits表示共享的锁个数,acquire方法就是检查锁个数是否大于0,大于则减一,获取成功,否则就等待,release就是将锁个数加一,唤醒第一个等待的线程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容