Java线程之信号量

 计数信号量用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。计数信号量还可以用来实现某种资源池,或者对容器施加边界。
Semaphore中管理者一组虚拟的许可,许可的数量可通过构造函数来指定。在互相操作时可以首先获得许可(只要还有剩余的许可),并在使用以后释放许可。如果没有许可,那么acquire将阻塞直到有许可(或者直到被中断或者操作超时)。release方法将返回一个许可给信号量。计算信号量的一种简化形式是二值信号量,即初始值为1的Semaphore,二值信号量可以用做互斥体,并不具备可重入的加锁语义:谁拥有这个唯一的许可,谁就拥有了互斥锁。
Semaphore可以用来实现资源池,例如数据库连接池。我们可以构造一个固定长度的资源池,当池为空时,请求资源将会失败,但你真正希望看到的行为是阻塞而不是失败,并且当池非空时解除阻塞。如果将Semaphore的计数值初始化为池的大小,并在从池中获取一个资源之前先首先调用acquire方法获取一个许可,在将资源返回给池之后调用release释放许可,那么acquire将一直阻塞直到资源池不为空。

public class BoundedHashSet<T> {
    private Set<T> set;
    private Semaphore sem;

    public BoundedHashSet(int bound) {
        this.set = Collections.synchronizedSet(new HashSet<T>());
        sem = new Semaphore(bound);//传入的许可数量,可以控制每次访问的线程的数量
    }

    public boolean add(T o) throws InterruptedException {
        sem.acquire();
        boolean wasAdded = false;
        try {
            wasAdded = set.add(o);
            return wasAdded;
        } finally {
            if (!wasAdded) {
                sem.release();
            }
        }
    }

    public boolean remove(Objects o) {
        boolean wasRemove = set.remove(o);
        if (wasRemove) {
            sem.release();
        }
        return wasRemove;
    }

}

 根据Semaphore特性,我们可以来控制每次访问资源的线程数量。

猜你喜欢

转载自blog.csdn.net/lmh_19941113/article/details/85048987