信号量Semaphore

时间 2019/5/29 15:39:22 加载中...

介绍

Semaphore,大家通常称为“信号量”。
信号量允许多个线程同时操作,后续的线程需要等待。信号量本质上是一系列许可的集合。线程需要获取到许可才可以执行,没有可用的许可,就只能等待。线程任务执行完毕后,可以归还许可给信号量。

信号量有公平和非公平两种,公平的话,则符合 First In,First out 原则,即先到先得,先到的线程可以先获得许可。

当资源有限的情况下,需要保护资源的使用时,可以使用信号量。

示例

停车场只有2个车位,来了5辆车,前面的2辆车进去后,后面的车只能等待前面的车出来,才能进去。

  1. package ThreadDemo.SemaphoreDemo;
  2. public class Car {
  3. private int number;
  4. public Car(int number){
  5. this.number = number;
  6. }
  7. @Override
  8. public String toString() {
  9. return "车" + this.number;
  10. }
  11. }

停车场

  1. package ThreadDemo.SemaphoreDemo;
  2. public class ParkingSpace {
  3. private Car[] spaces = new Car[2];
  4. public void park(Car car) {
  5. boolean find = false;
  6. for (int i = 0; i < spaces.length; i++) {
  7. Car item = spaces[i];
  8. if (item == null) {
  9. spaces[i] = car;
  10. System.out.println(car.toString() + "停放在" + i);
  11. find=true;
  12. break;
  13. }
  14. }
  15. if(find==false)
  16. System.out.println(car.toString() + "没找到车位");
  17. }
  18. public void go(Car car) {
  19. boolean find = false;
  20. for (int i = 0; i < spaces.length; i++) {
  21. Car item = spaces[i];
  22. if (item == car) {
  23. spaces[i] = null;
  24. System.out.println(car.toString() + "离开了" + i);
  25. find =true;
  26. break;
  27. }
  28. }
  29. if(find == false)
  30. System.out.println(car.toString() + "没有此车");
  31. }
  32. }

运行

  1. package ThreadDemo.SemaphoreDemo;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.Semaphore;
  5. public class demo02 {
  6. public static void main(String[] args) {
  7. ParkingSpace parkingSpace = new ParkingSpace();
  8. ExecutorService executorService = Executors.newCachedThreadPool();
  9. gl>Semaphore semaphore = new Semaphore(2); //一共2个许可
  10. for (int i=0; i<5; i++){
  11. int number = i+1;
  12. executorService.execute(() -> {
  13. try {
  14. Car car = new Car(number);
  15. gl>semaphore.acquire(); //获取许可
  16. parkingSpace.park(car);
  17. Thread.sleep(2000);
  18. parkingSpace.go(car);
  19. gl>semaphore.release(); //归还许可
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. });
  24. }
  25. executorService.shutdown();
  26. }
  27. }

若没有上面黄色部分的代码,即没有使用信号量的话,输出的结果为

车1停放在0
车2停放在1
车3没找到车位
车4没找到车位
车5没找到车位
车1离开了0
车2离开了1
车5没有此车
车4没有此车
车3没有此车

就会发现所有的车一下子全进了停车场。为了保证只有两辆车进入,使用信号量。输出的结果为

车1停放在0
车2停放在1
车1离开了0
车2离开了1
车3停放在0
车4停放在1
车3离开了0
车5停放在0
车4离开了1
车5离开了0

这就保证了,每次只有两辆车进入。

当然上面的输出,有可能是车辆5先进去的,为了保证 先来先得,可以使用 公平信号量

  1. Semaphore semaphore = new Semaphore(2,true);
扫码分享
版权说明
作者:SQBER
文章来源:http://www.sqber.com/articles/Semaphore.html
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。