Java Semaphore maximum?

左心房为你撑大大i 提交于 2019-12-25 07:48:48

问题


Is there a way of knowing what is the MAXIMUM number of permits that a semaphore object has ever had in its' lifetime? We initialize it like this:

Semaphore sem = new Semaphore(n);

and at times we acquire, and at times we release what we acquired. But there are certain situations when we need to release more than we acquired in order to increase the number of permits. Is there a way to know the MAXIMUM number of permits that ever was in this semaphore?


回答1:


The constructor is defined as public Semaphore(int permits). The maximum of int is 231 -1 = 2147483647 so this is your answer.




回答2:


Semaphore itself does not keep track of a maximum over its lifetime. Implementing a Semphore wrapper around it that keeps track of the maximum can be tricky. Here's a quick draft of such an implementation :

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();
    }
}

The MaxCounter may not be exactly in sync with the internally used semaphore . The internal semaphore may get a release/acquire which is handled from an external perspective as acquire/release. To every client of MySemaphore, though the behavior will be consistent. i.e. availablePermits() will never return a value that is higher than getMaximumEverAvailable()

disclaimer : code not tested*



来源:https://stackoverflow.com/questions/13959643/java-semaphore-maximum

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!