2012-12-19 93 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()

免責聲明:代碼沒有測試*