Java Semaphore - 如何获得已使用的许可证

Java Semaphore - How to get used permits

我们可以获得居留许可 availablePermits()

如何在运行时获取 usedPermits()maxPermits(例如,最大许可从 db 加载并且 db 值可能在信号量创建后发生变化)?

我当然可以在内存中记住最大许可数,但我想知道是否有简单的方法可以做到这一点

不幸的是,如果您不自己记录原始号码,这是不可能的。或者,您可以轻松地扩展 Semaphore 以具有上述功能(底部的示例实现)。

理论上(在Java实现中),信号量没有任何"original"许可数量的概念。使用信号量的已定义语义,您可以很好地使用 0 个许可对其进行初始化,并且在获取任何许可之前需要一些许可为 "released"。在实践中,我从未见过以这种方式使用的信号量,但这就是信号量的定义方式。

来自Java Semaphore documentation:

There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire(). Correct usage of a semaphore is established by programming convention in the application.

如您所见,如果我们自己不了解 "max permits" 信号量的设计方式,它们也无法告诉我们。

如果您将信号量视为 int 的包装器(它在很多方面都是如此),那么它就很清楚了:

假设我们有以下序列:

int permits = x;
permits--;
permits++;
// More unknown decrements/increments
permits--;

现在获取许可证数量很容易。在不知道 x 或同时不知道操作顺序的情况下,不可能告诉您已使用了多少。


扩展 Semaphore 以具有 usedPermits 方法的示例。

import java.util.concurrent.*;

class UsedTrackingSemaphore extends Semaphore {
    private int originalPermits;

    public UsedTrackingSemaphore(int permits) {
        super(permits);
        originalPermits = permits;
    }

    public UsedTrackingSemaphore(int permits, boolean fair) {
        super(permits, fair);
        originalPermits = permits;
    }

    public int usedPermits() {
        return originalPermits - availablePermits();
    }
}