今天寫代碼,嘗試使用了AtomicInteger這個類,感覺使用起來很爽,特别适用于高并發通路,下面貼一個簡單的例子:

CashierContext類部分代碼:
private Map<String, AtomicInteger> counter = new HashMap<String, AtomicInteger>();
private void initCounter() {
counter.put("cvm", new AtomicInteger(0));
}
//被調用一次自動+1
public MobileCashierViewModel getCvm() {
if (cvm != null) {
counter.get("cvm").incrementAndGet();
}
return cvm;
}
使用場景:
因為通過WS服務擷取MobileCashierViewModel 這個對象比較頻繁,會很影響系統資源,可以将cvm存入緩存中,想要檢視緩存cvm有多大價值,那麼可以設定一個計數,來統記cvm被調用的次數
然後将CashierContext放入ThreadLocal中,然後再寫一個過濾器,在過濾器裡面可以得到擷取這個服務從緩存中取的次數,這個就可以很容易看出來緩存價值。
那麼為什麼不使用記數器自加呢,例如count++這樣的,因為這種計數是線程不安全的,高并發通路時統計會有誤,而AtomicInteger為什麼能夠達到多而不亂,處理高并發應付自如呢,我們才看看AtomicInteger的源代碼:

private volatile int value;
大家可以看到有這個變量,value就是你設定的自加起始值。注意看它的通路控制符,是volatile,這個就是保證AtomicInteger線程安全的根源,熟悉并發的同學一定知道在java中處理并發主要有兩種方式:
1,synchronized關鍵字,這個大家應當都各種面試和筆試中經常遇到。
2,volatile修飾符的使用,相信這個修飾符大家平時在項目中使用的也不是很多。
這裡重點說一下volatile:
Volatile修飾的成員變量在每次被線程通路時,都強迫從共享記憶體重新讀取該成員的值,而且,當成員變量值發生變化時,強迫将變化的值重新寫入共享記憶體,這樣兩個不同的線程在通路同一個共享變量的值時,始終看到的是同一個值。
java語言規範指出:為了擷取最佳的運作速度,允許線程保留共享變量的副本,當這個線程進入或者離開同步代碼塊時,才與共享成員變量進行比對,如果有變化再更新共享成員變量。這樣當多個線程同時通路一個共享變量時,可能會存在值不同步的現象。
而volatile這個值的作用就是告訴VM:對于這個成員變量不能儲存它的副本,要直接與共享成員變量互動。
建議:當多個線程同時通路一個共享變量時,可以使用volatile,而當通路的變量已在synchronized代碼塊中時,不必使用。
缺點:使用volatile将使得VM優化失去作用,導緻效率較低,是以要在必要的時候使用。
本文轉自農夫山泉别墅部落格園部落格,原文連結:http://www.cnblogs.com/yaowen/p/6110032.html,如需轉載請自行聯系原作者