Semaphore管理对资源的访问许可数量

java.util.concurrent.Semaphore 是一个用于控制对一组资源的访问的同步辅助类。它可以看作是一个计数器,用于管理对资源的访问许可数量。下面是一个简单的例子,展示了如何使用 Semaphore 来控制对一组资源的访问。 假设我们有一个资源池,比如一个包含 5 个资源(比如 5 台打印机)的系统,我们希望限制同时访问这些资源的线程数量。我们可以使用 Semaphore 来实现这一点。

Semaphore 事例


import java.util.concurrent.Semaphore;

public class SemaphoreTemp {
    private final int numberOfResources;
    private final Semaphore semaphore;

    public SemaphoreTemp(int numberOfResources) {
        this.numberOfResources = numberOfResources;
        this.semaphore = new Semaphore(numberOfResources);
    }

    public void accessResource(String threadName) {
        try {
            // 请求一个许可
            semaphore.acquire();
            System.out.println(threadName + " has acquired a resource.");

            // 模拟资源使用
            Thread.sleep((int) (Math.random() * 1000));

            System.out.println(threadName + " is releasing the resource.");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println(threadName + " was interrupted while waiting for a resource.");
        } finally {
            // 释放许可
            semaphore.release();
        }
    }

    public  void 打印机(String threadName) {

        try {
            // 请求一个许可
            semaphore.acquire();
            System.out.println(threadName + " has acquired a 打印机.");

            // 模拟资源使用
            Thread.sleep((int) (Math.random() * 1000));

            System.out.println(threadName + " is releasing the 打印机.");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println(threadName + " was interrupted while waiting for a 打印机.");
        } finally {
            // 释放许可
            semaphore.release();
        }
    }

    public static void main(String[] args) {
        int numberOfResources = 5;
        SemaphoreTemp resourcePool = new SemaphoreTemp(numberOfResources);

        // 创建并启动多个线程来访问资源
        for (int i = 0; i < 10; i++) {
            int threadNumber = i + 1;
            if(i%2==0){
                new Thread(() -> resourcePool.accessResource("Thread-" + threadNumber)).start();
            }
            else {
                new Thread(() -> resourcePool.打印机("Thread-" + threadNumber)).start();
            }
        }
    }
}

解释

  1. ResourcePool 类:
    • numberOfResources 变量表示资源池中资源的数量。
    • semaphore 是一个 Semaphore 实例,初始化为 numberOfResources。这意味着最多可以有 numberOfResources 个线程同时获取许可并访问资源。
  2. accessResource 方法:
    • 使用 semaphore.acquire() 方法请求一个许可。如果当前没有可用的许可,线程将被阻塞,直到有许可可用。
    • 模拟资源使用,通过 Thread.sleep 方法让线程暂停一段时间。
    • 使用 semaphore.release() 方法释放许可,以便其他线程可以获取许可并访问资源。
  3. 打印机 方法                
    同accessResource 方法一致,共有5个资源
  4. main 方法:
    • 创建一个 ResourcePool 实例,资源数量为 5。
    • 启动 10 个线程,每个线程都尝试访问资源。由于资源池只有 5 个资源,最多只能有 5 个线程同时访问资源,其他线程将被阻塞,直到有资源可用。

运行结果

运行这个程序,你会看到类似以下的输出(输出顺序可能会有所不同):

Thread-5 has acquired a resource.
Thread-7 has acquired a resource.
Thread-6 has acquired a 打印机.
Thread-4 has acquired a 打印机.
Thread-10 has acquired a 打印机.
Thread-7 is releasing the resource.
Thread-1 has acquired a resource.
Thread-6 is releasing the 打印机.
Thread-2 has acquired a 打印机.
Thread-2 is releasing the 打印机.
Thread-3 has acquired a resource.
Thread-5 is releasing the resource.
Thread-9 has acquired a resource.
Thread-4 is releasing the 打印机.
Thread-8 has acquired a 打印机.
Thread-8 is releasing the 打印机.
Thread-3 is releasing the resource.
Thread-10 is releasing the 打印机.
Thread-1 is releasing the resource.
Thread-9 is releasing the resource.

通过这种方式,Semaphore 确保在任何时候,最多只有 numberOfResources=5个线程可以访问资源。

其他方法

带参数的acquire方法 尝试获取指定数量的许可。 semaphore.acquire(2); // 获取2个许可

tryAcquire方法 尝试获取许可,如果许可立即可用,则获取许可并返回true,否则返回false。 boolean success = semaphore.tryAcquire();

带超时的tryAcquire方法 尝试在给定的等待时间内获取许可。 boolean success = semaphore.tryAcquire(10, TimeUnit.SECONDS); // 最多等待10秒

带参数的release方法 释放指定数量的许可。 semaphore.release(2); // 释放2个许可 availablePermits方法 返回当前可用的许可数量。 int permits = semaphore.availablePermits(); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值