并发包中的 Semaphore 的使用

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这种计数器结构,虽然有类似功能,但其实不存在真正意义的持有者,除非我们进行扩展包装。

猜你喜欢

转载自blog.csdn.net/qq_33404395/article/details/81304623
今日推荐