发布于 4年前

Semaphore信号量用法示例

概要

Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库的Semaphore可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire()获取一个许可,如果没有就等待,而release()释放一个许可。用来控制资源同时访问个数

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

构造函数

Semaphore提供了一个带有boolean参数的构造方法,true代表公平锁,false代表非公平锁,默认实现是非公平锁。

public (int permits); 
public (int permits, boolean fair); //创建具有给定许可数的公平(true)或非公平(false) Semaphore

普通方法

public void acquire() //从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断
public void acquire(int permits) //从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断
public void release() //释放一个许可,将可用的许可数增加1
public void release(int permits) //释放给定数目的许可,将其返回到信号量
public boolean isFair() //如果此信号量的公平设置为true,则返回 true

停车案例

package com.zsr.test.Semaphore;
import java.util.concurrent.Semaphore;
class Car implements Runnable {
  private final Semaphore parkingspace;
  private int carNo;
  /**
   * @param parkingspace
   * @param carNo
   */
  public Car(Semaphore parkingspace, int carNo) {
    this.parkingspace = parkingspace;
    this.carNo = carNo;
  }
  public void run() {
    try {
         parkingspace.acquire();
         parking();
         Thread.sleep(300);
         parkingspace.release();
         leaving();
     } catch (InterruptedException e) {
         e.printStackTrace();
   }
  }
  private void parking() {
    System.out.println(String.format("%d号车泊车", carNo));
  }
  private void leaving() {
     System.out.println(String.format("%d号车离开车位", carNo));
  }
 }
 public class ParkingCars {
  private static final int NUMBER_OF_CARS = 5;
  private static final int NUMBER_OF_PARKING_SPACE = 3;
  public static void main(String[] args) throws InterruptedException {
    Semaphore parkingSpace = new Semaphore(NUMBER_OF_PARKING_SPACE, true);
    for (int carNo = 1; carNo <= NUMBER_OF_CARS; carNo++) {
      new Thread(new Car(parkingSpace, carNo)).start();
    }
    Thread.sleep(3000);
    /*
     * 输出还有几个可以用的资源数
     */
     System.out.println(parkingSpace.availablePermits() + " 个停车位可以用!");
  }
}

输出结果:

 2号车泊车
 1号车泊车
 3号车泊车
 2号车离开车位
 4号车泊车
 3号车离开车位
 1号车离开车位
 5号车泊车
 4号车离开车位
 5号车离开车位
 3 个停车位可以用!
©2020 edoou.com   京ICP备16001874号-3