Semaphore
定义:
一个计数信号量。它通过控制一定数量的允许(permit)的方式,来达到限制通用资源访问的目的。你可以想象一下这个场景,在车站、机场等出租车时,当很多空出租车就位时,为防止过度拥挤,调度员指挥排队等待坐车的队伍一次进来 5 个人上车,等这 5 个人坐车出发,再放进去下一批,这和 Semaphore 的工作原理有些类似。
使用示例:
public class SemaphoreDemo implements Runnable {
private String name;
private Semaphore semaphore;
public SemaphoreDemo(Semaphore semaphore) {
this.semaphore = semaphore;
}
public static void main(String[] args) throws InterruptedException {
/* 给定的许可数 5,限制每次5个线程进入 */
Semaphore semaphore = new Semaphore(5);
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new SemaphoreDemo(semaphore));
t.start();
}
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"等待获取许可");
/* 从此信号量获取一个许可,在获取到一个许可前将一直将线程阻塞 */
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"获取到一个许可");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
/* 释放给定数目的许可,其他线程才能获取到 */
semaphore.release();
System.out.println(Thread.currentThread().getName()+"释放一个许可");
}
}
}
根据上面的代码,10个线程一次只能有5个获取到许可
(另外5个进入等待),当有释放许可
的时候其他的线程才能再次获取,并进入操作。
若将释放许可
的操作注释,其他线程会无法继续执行其他操作,继续处于等待状态。
总结:
如果 Semaphore
的数值被初始化为 1,那么一个线程就可以通过 acquire ()
进入互斥状态,本质上和互斥锁是非常相似的。但是区别也非常明显,比如互斥锁是有持有者的,而对于 Semaphore
这种计数器结构,虽然有类似功能,但其实不存在真正意义的持有者,除非我们进行扩展包装。