为什么 Java 允许使用否定许可初始化信号量?

问题描述

在信号量 (java.util.concurrent.Semaphore) 的初始化期间,我对否定许可没有理性。

我知道对 release() 方法调用最终可能会使信号量的许可大于等于 1 (>=1),以便稍后其他线程可以获得许可。或者稍后在程序执行期间,当更多线程在执行acquire()方法时正在等待许可时,信号量可能会获得否定许可..

但是,我没有得到任何实际用例,我会初始化具有否定许可的信号量。

参考示例代码

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

    public static void main(String[] args) throws InterruptedException {
        // Todo Auto-generated method stub
        Semaphore s = new Semaphore(-2);
        System.out.println(s.availablePermits());
        s.release(3); // adding 3 permits
        System.out.println(s.availablePermits()); // Now it has 1 permit        
    }
}

解决方法

如果您在创建信号量时知道某些资源已经在使用,它可能很有用。例如初始化中使用的那些资源。

,

为什么 java 不允许在信号量构造函数中使用负数?信号量只是一种限制对某些资源的访问的机制。如果我们想从一开始就限制访问,我们不妨将信号量初始化为负值,并确保暂时没有线程会接触该资源。

javadoc 很清楚:

@param 允许可用的初始许可数量。

这个值可能是负数,在这种情况下释放 必须在授予任何获取之前发生。

您可能处于这样一种情况,从一开始,您就需要等待某些资源打开并可用,然后才能开始使用。


例如:假设您有 3 个线程正在构建您需要处理的文件。此操作需要时间。完成所有 3 个线程后,您才能继续工作。您必须等待这三个线程释放信号量才能继续工作。现在,这可能不是解决问题的好方法,但至少可以通过初始信号量否定许可来实现。


发布了另一个具有相同咒语的示例here