您的位置:首页 > 编程语言

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

2017-10-09 14:12 267 查看
本文的目的是要分析信号量内部的实现流程,不深入信号量底层的实现细节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));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息