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 个停车位可以用!