AtomicInteger在实际项目中的应用

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

原文地址:https://www.cnblogs.com/yutingliuyl/p/7229783.html