セマフォオブジェクトがその存続期間中にこれまでに持っていた許可の最大数を知る方法はありますか?次のように初期化します。
Semaphore sem = new Semaphore(n);
取得することもあれば、取得したものをリリースすることもあります。ただし、許可の数を増やすために、取得した以上のリリースが必要な場合があります。このセマフォにこれまでにあった許可の最大数を知る方法はありますか?
セマフォ自体は、その存続期間中の最大値を追跡しません。最大値を追跡する Semphore ラッパーを実装するのは難しい場合があります。このような実装の簡単なドラフトを次に示します。
public final class MySemaphore {
private final Semaphore semaphore;
private final AtomicReference<MaxCounter> maxCounter = new AtomicReference<>();
public MySemaphore(int initialAvailable) {
this.semaphore = new Semaphore(initialAvailable);
maxCounter.set(new MaxCounter(initialAvailable, initialAvailable));
}
private static final class MaxCounter {
private final int value;
private final int max;
public MaxCounter(int value, int max) {
this.value = value;
this.max = max;
}
public MaxCounter increment() {
return new MaxCounter(value + 1, Math.max(value + 1, max));
}
public MaxCounter decrement() {
return new MaxCounter(value - 1, max);
}
public int getValue() {
return value;
}
public int getMax() {
return max;
}
}
public void acquire() throws InterruptedException {
semaphore.acquire();
for (;;) {
MaxCounter current = maxCounter.get();
if (maxCounter.compareAndSet(current, current.decrement())) {
return;
}
}
}
public void release() {
for (;;) {
MaxCounter current = maxCounter.get();
if (maxCounter.compareAndSet(current, current.increment())) {
break;
}
}
semaphore.release();
}
public int availablePermits() {
return maxCounter.get().getValue();
}
public int getMaximumEverAvailable() {
return maxCounter.get().getMax();
}
}
MaxCounter は、内部で使用されるセマフォと正確に同期していない可能性があります。内部セマフォは、外部の観点から取得/解放として処理される解放/取得を取得する場合があります。動作は一貫していますが、MySemaphore のすべてのクライアントに対して。つまりavailablePermits()
、より高い値を返すことはありません getMaximumEverAvailable()
免責事項: コードはテストされていません*
コンストラクタは次のように定義されpublic Semaphore(int permits)
ます。int の最大値は 2 31 -1 = 2147483647 なので、これが答えです。