1. 程式人生 > >AtomicInteger在實際項目中的應用

AtomicInteger在實際項目中的應用

ger log 筆試 設有 zed fad end attr ext

AtomicInteger。一個提供原子操作的Integer的類。

在Java語言中,++i和i++操作並非線程安全的。在使用的時候,不可避免的會用到synchronized關鍵字。

而AtomicInteger則通過一種線程安全的加減操作接口。

樣例:Java代碼:

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中,然後再寫一個過濾器,在過濾器裏面能夠得到獲取這個服務從緩存中取的次數,這個就能夠非常easy看出來緩存價值。

那麽為什麽不使用記數器自加呢,比如count++這種,由於這種計數是線程不安全的。高並發訪問時統計會有誤,而AtomicInteger為什麽能夠達到多而不亂。處理高並發應付自如呢,我們才看看AtomicInteger的源碼:

Java代碼

private volatile int value;  

大家能夠看到有這個變量,value就是你設置的自加起始值。註意看它的訪問控制符。是volatile,這個就是保證AtomicInteger線程安全的根源,熟悉並發的同學一定知道在java中處理並發主要有兩種方式:
1。synchronized關鍵字。這個大家應當都各種面試和筆試中常常遇到。


2。volatile修飾符的使用。相信這個修飾符大家平時在項目中使用的也不是非常多。

這裏重點說一下volatile:
Volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存又一次讀取該成員的值,並且。當成員變量值發生變化時,強迫將變化的值又一次寫入共享內存。這樣兩個不同的線程在訪問同一個共享變量的值時,始終看到的是同一個值。

java語言規範指出:為了獲取最佳的執行速度,同意線程保留共享變量的副本,當這個線程進入或者離開同步代碼塊時。才與共享成員變量進行比對,假設有變化再更新共享成員變量。

這樣當多個線程同一時候訪問一個共享變量時。可能會存在值不同步的現象。

而volatile這個值的作用就是告訴VM:對於這個成員變量不能保存它的副本,要直接與共享成員變量交互。

建議:當多個線程同一時候訪問一個共享變量時,能夠使用volatile。而當訪問的變量已在synchronized代碼塊中時,不必使用。
缺點:使用volatile將使得VM優化失去作用,導致效率較低。所以要在必要的時候使用。

引用自:
http://haininghacker-foxmail-com.iteye.com/blog/1401346

AtomicInteger在實際項目中的應用