多線程統計次數問題:即count++


場景:日志需要統計每天數據上傳的次數和上傳的數據量。

     如果是單線程可以使用簡單的int count = 0;count++,但很多情況都是多線程環境所以就不能單純的使用count++了!!!

     多線程環境采用 java.util.concurrent.atomic 下的AtomicLong類,該類的介紹可看API文檔。可以用原子方式更新的 long 值。有關原子變量屬性的描述,請參閱 java.util.concurrent.atomic 包規范。AtomicLong 可用在應用程序中(如以原子方式增加的序列號),並且不能用於替換 Long。但是,此類確實擴展了 Number,允許那些處理基於數字類的工具和實用工具進行統一訪問。每天都要把統計的次數置為0,可以使用定時器,每天零點零分將次數重置為0,該方法不易拓展;另一種方法是使用全局變量時間戳,判斷當前日期是不是與時間戳相等,如果是就說明今天的次數累加;如果不是就要把時間戳重置為當天的日期,並把次數重置為0。多線程情況下采用鎖加double check方法確保解決並發問題!

 1 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 2 
 3 /**
 4      * 獲得當前日期
 5      * <p>
 6      * 日期格式yyyy-MM-dd
 7      * 
 8      * @return
 9      */
10     public static String currentDate() {
11         return DATE_FORMAT.format(new Date());
12     }

 

 1     //上傳次數
 2     private final AtomicLong count = new AtomicLong(0);
 3     
 4     //上傳數據量
 5     private final AtomicLong dataSize = new AtomicLong(0);
 6     
 7     //時間戳
 8     private String today = DateUtils.currentDate();
 9     
10     public void getLog(Integer size){
11         String systTime = DateUtils.currentDate();
12         //如果日期不是當天的
13         if(today!=null && !systTime.equals(today)){
14             synchronized (today) {
15                 if(today!=null && !systTime.equals(today)){
16                     today=systTime;
17                     count.set(0);
18                     dataSize.set(0);
19                 }
20             }
21         }
22         count.incrementAndGet();
23         dataSize.addAndGet(size);
24         if(logger.isInfoEnabled()) {
25             logger.info(String.format("That day receive data the %sth times,total %s data !",count.get(),dataSize.get()));
26         }
27     }

    還有很關鍵的一個問題不要忽略,就是該類是單例的,這樣確保所有線程共享同一個count,dataSize只有一個對象!或者將count,dataSize設置成static!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM