Semaphore的使用和操作系统中的信号量的使用差不多,可以类比去理解。
Semaphore用于限制可以访问某些资源(物理或逻辑的)的线程数目,他维护了一个许可证集合,有多少资源需要限制就维护多少许可证集合,假如这里有N个资源,那就对应于N个许可证,同一时刻也只能有N个线程访问。一个线程获取许可证就调用acquire方法,用完了释放资源就调用release方法。
停车场案例代码实现:
public class CarDemo {
public static void main(String[] args) {
//创建Semaphore
Semaphore sp=new Semaphore(5);
Thread[] car=new Thread[10];
for (int i = 0; i < 10; i++) {
car[i]=new Thread(()->{
//请求许可
try {
sp.acquire();
System.out.println(Thread.currentThread().getName()+"可以进停车场");
} catch (InterruptedException e) {
e.printStackTrace();
}
//使用资源
try {
int val= new Random().nextInt(10);
TimeUnit.SECONDS.sleep(val);
System.out.println(Thread.currentThread().getName()+"停留了"+val+"秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
//离开(释放资源)
try {
sp.release();
System.out.println(Thread.currentThread().getName()+"离开停车场");
} catch (Exception e) {
e.printStackTrace();
}
},"car["+i+"]");
car[i].start();
}
}
}
其他方法:
在上面我们使用最基本的acquire方法和release方法就可以实现Semaphore最常见的功能,不过其他方法还是需要我们去了解一下的。
1、acquire(int permits)
从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。就好比是一个学生占两个窗口。这同时也对应了相应的release方法。
2、release(int permits)
释放给定数目的许可,将其返回到信号量。这个是对应于上面的方法,一个学生占几个窗口完事之后还要释放多少
3、availablePermits()
返回此信号量中当前可用的许可数。也就是返回当前还有多少个窗口可用。
4、reducePermits(int reduction)
根据指定的缩减量减小可用许可的数目。
5、hasQueuedThreads()
查询是否有线程正在等待获取资源。
6、getQueueLength()
返回正在等待获取的线程的估计数目。该值仅是估计的数字。
7、tryAcquire(int permits, long timeout, TimeUnit unit)
如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。
8、acquireUninterruptibly(int permits)
从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。
来源:CSDN
作者:清风不灭
链接:https://blog.csdn.net/weixin_40391011/article/details/104735719