JUC

Semaphore


Semaphore和ReentrantLock类似,获取许可有公平策略和非公平许可策略,默认情况下使用非公平策略。

  当初始值为1时,可以用作互斥锁,并具备不可重入的加锁语义。

  Semaphore将AQS的同步状态用于保存当前可用许可的数量。

实现资源池:

  一个固定长度的资源池,当池为空时,请求资源会失败。

  使用Semaphore可以实现当池为空时,请求会阻塞,非空时解除阻塞。

  也可以使用Semaphore将任何一种容器变成有界阻塞容器。

应用场景:

以一个停车场是运作为例。假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了六辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。

这个停车系统中,每辆车就好比一个线程,看门人就好比一个信号量,看门人限制了可以活动的线程。假如里面依然是三个车位,但是看门人改变了规则,要求每次只能停两辆车,那么一开始进入两辆车,后面得等到有车离开才能有车进入,但是得保证最多停两辆车。对于Semaphore类而言,就如同一个看门人,限制了可活动的线程数。

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(3);//最多3个车位
        for (int i = 0; i < 6; i++) {//6辆车
            new Thread(()->{
                try {
                    semaphore.acquire();//占用车位
                    System.out.println(Thread.currentThread().getName()+" 抢到车位。");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName()+" 离开车位。");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();//释放信车位
                }
            },String.valueOf(i)).start();
        }
    }
}
1 抢到车位。
2 抢到车位。
3 抢到车位。

2 离开车位。
3 离开车位。
1 离开车位。
5 抢到车位。
0 抢到车位。
4 抢到车位。

0 离开车位。
5 离开车位。
4 离开车位。
  • 作者:低调做个路人 (扫码联系作者)
  • 发表时间:2019-11-30 19:48:23
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 评论