1

簡單要求: - 以每日,每小時或每分鐘爲基礎重置爲0的命名計數器。下一個超出限制的請求將重置,而不是遞增。無需重設定時器/鬧鐘時間。 - API應該很簡單 - 線程安全Java中應用程序數據的可復位線程安全計數器

示例用法。保持計數器的特定應用程序/業務事件用於記錄或檢查限制。 檢查特定資源的使用是否超過每日限制並停止訪問它。

回答

1

更新:最新版本在GitHub上張貼的人誰是有興趣 - https://github.com/mickyr/Awesome-Counter

我最小實現爲止。如果您發現任何問題/改進方面,請評論。反饋,消極或積極的歡迎。這將是一個學習的機會:

復位計數器類:

import java.util.concurrent.atomic.AtomicInteger; 

public class ResettableCounter { 
    private String policyString; 
    private AtomicInteger count; 

    public ResettableCounter(String name, AtomicInteger counter) { 
     this.policyString = name; 
     this.count = counter; 
    } 

    public String getPolicyString() { 
     return policyString; 
    } 

    public void setPolicyString(String policyString) { 
     this.policyString = policyString; 
    } 

    public AtomicInteger getCount() { 
     return count; 
    } 

} 

CounterPolicy枚舉

public enum CounterPolicy{ 
    YEARLY("yyyy"), 
    MONTHLY("yyyy/MM"), 
    DAILY("yyyy/MM/dd"), 
    HOURLY("yyyy/MM/dd hh"), 
    PERMINUTE("yyyy/MM/dd hh:mm"); 

    private String format; 

    private CounterPolicy(String format) { 
     this.format = format; 
    } 

    public String getFormat(){ 
     return this.format; 
    } 
} 

ResettableCounter Registry類:

import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.TimeZone; 
import java.util.concurrent.ConcurrentHashMap; 
import java.util.concurrent.atomic.AtomicInteger; 

import CounterPolicy; 
import ResettableCounter; 

public class ResetableCounterRegistry { 
    private ConcurrentHashMap<String, ResettableCounter> counterRegistry = new ConcurrentHashMap<String, ResettableCounter>(); 
    private CounterPolicy policy = CounterPolicy.DAILY; 

    public int incrementCount(String counterName){ 
     ResettableCounter counter = counterRegistry.get(counterName);  
     DateFormat dateFormat = new SimpleDateFormat(policy.getFormat()); 
     Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
     if(counter==null)counterRegistry.putIfAbsent(counterName, new ResettableCounter(dateFormat.format(cal.getTime()), new AtomicInteger())); 
     counter=counterRegistry.get(counterName); 
     if(!dateFormat.format(cal.getTime()).equals(counter.getPolicyString())){ 
      int count = counter.getCount().get(); 
      if(counter.getCount().compareAndSet(count, 0)) 
       counter.setPolicyString(dateFormat.format(cal.getTime())); 
      else counter.getCount().incrementAndGet(); 
     } 
     else counter.getCount().incrementAndGet(); 
     return counter.getCount().get(); 
    } 

    public void setPolicy(CounterPolicy policy) { 
     this.policy = policy; 
    } 
} 

正如我所說這是最小的實現,但希望可以喚起良好的對話或幫助有類似用例的人。