2012-12-19 60 views
0

有没有办法知道信号量对象在其“生命周期”中曾经拥有过的最大许可数量是多少? 我们初始化它像这样:Java信号量最大?

Semaphore sem = new Semaphore(n); 

,并在次我们获得的,有时我们释放我们获得什么。但是在某些情况下,为了增加许可证的数量,我们需要发布更多的数据。有没有办法知道曾经在这个信号量下的最大许可数量?

+0

不要认为这是可能的标准信号量。你想达到什么目的? –

回答

2

构造函数定义为public Semaphore(int permits)。 int的最大值是2 -1 = 2147483647所以这是你的答案。

+0

对于32位体系结构。 – czchlong

+2

到目前为止,我知道每次被定义为一个4字节的值都是一个int。但我现在检查一下。 – rekire

+0

哈哈不,那不是我的问题。我的问题是我曾经输入到这个特定信号量的最大值。 – TheNotMe

2

信号量本身没有跟踪其最长的最大值。实现围绕它的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()

免责声明:代码没有测试*