Java多线程并发工具类-Semaphore工具解说

通过前面的学习,我们已经知道了Java多线程并发场景中使用对照多的两个工具类:做加法的CycliBarrier工具以及做减法的CountDownLatch工具并对这两个工具举行了对照。我们发现这两个工具要么是做加法,要么是做减法的。那么有没有既做加法也做减法的呢?固然有了。Semaphore这个工具类就可以实现One out one in的。

本文主要内容:Semaphore是什么?从生涯中例子中来明白Semaphore;代码演示;总结。通过总结-明白-代码演示-再总结这四个步骤让人人来深刻的明白。

本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《并发工具类》教程的第三篇:《Java多线程下信号量》。

一:Semaphore是什么?

Semaphore中文意思:信号量。

来看看JavaAPI中对semaphore工具的注释:


什么意思呢?

简朴明白来说,Semaphore:信号量主要用于两个目的:一个是用于多个共享资源的互斥使用;另一个用于并发线程数目的控制。什么意思呢?我们来从生涯中的例子来明白。

二:从生涯中例子中来明白Semaphore

案例一:抢车位

自驾游的同伙一样平常都市遇到这样的烦恼:去景区嬉戏,停车对照贫苦。由于停车场中的车位数目是一定的。当车位满了以后,其他想要进入停车场停车的车辆只能守候。等到其他车辆出来之后,才可以进入。站在并发角度来剖析的话:停车场有多个停车位(多个共享资源),每个车辆只能停在其中一个位置上(互斥使用的),停车场的停车位是牢固的(并发线程数目的控制)。这样是不是就好明白了?若是照样欠好明白,接着看下面这个案例

案例二:海底捞吃火锅

去海底捞吃火锅的时刻,海底捞园地就餐桌数目是牢固的,假设有5桌。现在来了8小我私家,那么其他3个就需要在门口候餐区守候加号。当有其他桌吃完脱离之后,进去一个。简图如下:

三:代码演示

我们就来模拟海底捞吃火锅的场景。


3.1:为什么要使用Semaphore?

为什么不能使用其他两个同步工具类呢?

凭据CountDownLatch的特征,只能使用一次的特征来说,海底捞这种场景固然不能够使用了。由于开个店不可能只使用一次。

CyclicBarrier,虽然可以使用多次,然则需要reset之后才可以多次使用。意思就是,只有等餐厅内里5个桌的客人都吃完之后,才可以让其他人进来就餐的。这种情形也是不符合营业逻辑的。

而Semaphore可以做到One out One in 很适合海底捞的场景。以是,经由剖析,我们可以获得如下代码。

代码演示:

餐桌工具:


执行方式:


运行效果:


从运行效果中,我们可以看到一个进入一个就脱离,一个脱离餐桌下一位就进入餐厅就餐。到达我们预期效果了。

四:总结

4.1:使用语法

在声明smaphore的时刻需要设置线程数目。然后使用acquire获取资源。在finally方式内里挪用release方式举行释放资源。如下图:


4.2:内部主要组成

4.2.1:三个内部类:


看到这三个类是不是很熟悉?对就是我们前面先容的ReentrantLock和ReentrantReadWriteLock这两个工具内里都存在的。继续AQS的Sync类以及公正锁的FairSync类和非公正锁的NonfairSync类。同样,semaphore也支持在组织器中指定是公正照样非公正的:


4.2.2:主要方式

主要的方式获取和释放方式:

获取资源的:

acquire()/acquire(int permits):获取资源(许可证)/获取指定个数的资源

释放资源:

release()/release(int permits):释放资源/释放指定个数的资源

其他方式:

阻止获取资源:

acquireUninterruptibly()/acquireUninterruptibly(int permits):从这个信号灯获取许可证,阻止一个可用的/阻止指定数目的

获取当前可以用的资源数目: int availablePermits()

另有其他许多方式。凯哥这里就不逐一先容了。人人可以自行查看API

4.3:实现原理

看到Sync这个内部类之后,人人就应该想到了凯哥(kaigejava)在之前先容过的AQS工具了。没错,Semaphore就是使用AQS和CAS来实现资源的获取和释放的。在这里凯哥就不赘述了。人人可以看看前面凯哥先容并发容器的同步器相关文章,内里凯哥做了详细的先容。

                                                                        欢迎来聊~