Semaphore源码解析


Semaphore简介:
线程上的信号量机制。
通过 acquire() 获取一个许可,没有便阻塞等待,release() 释放一个许可。

原理:实现又是基于AQS的共享锁。并且支持公平和非公平

其实就是初始化了一个AQS上的state,每次acquire就是去state上尝试减一,每次release就是去state上加一,

内部类及构造器:

维护了三个内部类。经典的aqs写法
在这里插入图片描述
公平和非公平两种都有对应的实现

构造器:

	//非公平
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }
    //可以指定是否公平
	public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }
    NonfairSync(int permits) {
         super(permits);
    }
    Sync(int permits) {
         setState(permits);
    }
    //最后是来到AQS当中来设置state来了
	protected final void setState(int newState) {
        state = newState;
    }
    
重要方法:
获取许可:
//调用的是aqs共享锁中的可打断方法
 public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
//一次甚至可以去多获取几个许可
 public void acquire(int permits) throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireSharedInterruptibly(permits);
    }
    
//该方法来自于AQS,使用的tryAcquireShared需要我们重写
 public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
            //如果acquire没有了许可,获取不到才会阻塞,具体要看aqs源码
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }


//再次回归aqs的使用,只需重写tryacquireshared
protected int tryAcquireShared(int acquires) {
            return nonfairTryAcquireShared(acquires);
}

//继续调用Sync中实现的方法,可以看出,尝试获取许可的过程实际上就是去尝试在state上减的过程
final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

以上就是去或区域许可的流程,如果不够就会陷入阻塞。直到获取到。
当然了,Semaphore是支持可否打断的,上面是可以打断的,当然还有不能打断的

//在Semaphore里都差不多。但具体可打断原理仍然要看AQS
 public void acquireUninterruptibly() {
        sync.acquireShared(1);
    }
public void acquireUninterruptibly(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.acquireShared(permits);
    }

还有可以尝试获取,获取不到无所谓不会阻塞的实现:


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

//下面两个方法可以去指定尝试时间,都是基于AQS
public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
        throws InterruptedException {
        if (permits < 0) throw new IllegalArgumentException();
        return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
    }
public boolean tryAcquire(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

下面就看释放许可

释放许可
    public void release() {
        sync.releaseShared(1);
    }
	public void release(int permits) {
        if (permits < 0) throw new IllegalArgumentException();
        sync.releaseShared(permits);
    }
//AQS中的方法
 	public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

//就是一个通过CAS去释放许可,也就是去加state的过程
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;
            }
        }

除此以外
剩下的就都是辅助方法了。AQS强大无比

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现码+数据集+超详细注释.zip

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值