并发编程之同步机制(一):Semphore信号量

本文的目的是要分析信号量内部的实现流程,不深入信号量底层的实现细节AQS(将会有另外一篇文章分析),让读者能够理解信号量内部结构和调用流程。

Semaphore:内部持有一系列的许可(permit),acquire操作会被阻塞直到有足够多的许可可用,最后会占用这些许可;release操作会归还许可让阻塞的acquire操作获取。Semaphore作用是限制多线程同时正确某一资源(资源可以是某个对象,可以是某种行为,例如创建某一对象的权利,销毁某一对象的权利)。

从上面的定义,可以看到主要有几个概念:许可,获取,和释放。Semaphore信号量的作用显然就是维护许可,提供许可获取和释放功能。首先,我们可以想到许可是否可用,显然许可是具有一定状态的,例如0:代表不可用,1:代表可用等,那么Semaphore信号量是如何标识许可的状态特征的呢?

获取:肯定有个获取者(accquirer),获取者自身有以下特点:1)优先级不一样,有些高,有些低,就好比富人和穷人;2)获取者素质不太一样,有些获取者霸占许可一直不归还,有些获取者及时归还;3) 获取者有可能需要同时获取多个许可的需求;获取者在获取许可过程中显然也会有一些特点:1)获取者可能大量同时获取相同的许可,导致竞争非常激烈;2)获取者如果没有获取许可时一直等待,有些希望有许可时在通知他们;3)获取者获取并持有许可用,获取者死亡,那么许可怎么归还给Semaphore。

释放:获取者在释放过程中,相对来说就比较简单,只需要通知Semaphore,告诉不需要许可了即可。

因此,下面将从Semaphore,获取者和许可三者关系出发,分析三者之间的关系。

当我们创建Semaphore时,需要制定许可个数以及是否采用公平同步器,在Semaphore中,公正Semaphore是指当Semaphore中有获取许可操作时不允许当前获取许可操作成功,直接返回失败;不公平Semaphore则获取操作基于CAS机制不断操作处理,不分先后,这会导致后面的获取操作有可能先于前面操作获得许可,呈现不公平。

先看Semaphore结构,整体包括获取许可调用函数,超时获取许可调用函数,维护许可信息函数,和释放等操作。

首先分析acquire方法,该方法支持线程中断,一旦发生线程中断,直接跳出获取操作,向上抛出InterrputedException异常。

publicvoid acquire() throws InterruptedException {
   
sync.acquireSharedInterruptibly(1);
}

进入sync.acquireSharedInterruptibly(integer)方法。首先及时校验Thread是否处于已中断状态,之后尝试获取许可,如果获取失败,进入阻塞获取流程(在这个循环中会不断检测线程是否发生中断)。

publicfinal void acquireSharedInterruptibly(int arg)
       
throws InterruptedException {
   
if (Thread.interrupted())
       
throw new InterruptedException();
    if
(tryAcquireShared(arg) < 0)
        doAcquireSharedInterruptibly(arg)
;
}

进入tryAcquire方法,该方法主要是获取信号量,不成功返回false,成功返回true,不阻塞,有明确结果返回。

publicboolean tryAcquire() {
   
return sync.nonfairTryAcquireShared(1) >= 0;
}

进入tryAcquire(int,long,TimeUint)方法,首先判断是否发生线程中断,如未发生中断则进入tryAcquireSharedNanos方法(该方法会首先获取一次许可,未获取许可则进入指定时间段内轮询)。

publicboolean tryAcquire(int permits, long timeout, TimeUnit unit)
   
throws InterruptedException {
   
if (permits < 0) throw new IllegalArgumentException();
    return
sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值