`

AtomicInteger与Volatile修饰

 
阅读更多

今天写代码,尝试使用了AtomicInteger这个类,感觉使用起来很爽,特别适用于高并发访问,下面贴一个简单的例子:

Java代码  收藏代码
  1. CashierContext类部分代码:  
  2.   
  3. private Map<String, AtomicInteger> counter          = new HashMap<String, AtomicInteger>();  
  4.   
  5.   
  6. private void initCounter() {  
  7.      counter.put("cvm"new AtomicInteger(0));  
  8. }  
  9.   
  10. //被调用一次自动+1  
  11.   
  12. public MobileCashierViewModel getCvm() {  
  13.   
  14.         if (cvm != null) {  
  15.             counter.get("cvm").incrementAndGet();  
  16.         }  
  17.         return cvm;  
  18.     }  

 

使用场景:

因为通过WS服务获取MobileCashierViewModel 这个对象比较频繁,会很影响系统资源,可以将cvm存入缓存中,想要查看缓存cvm有多大价值,那么可以设置一个计数,来统记cvm被调用的次数

 

 

然后将CashierContext放入ThreadLocal中,然后再写一个过滤器,在过滤器里面可以得到获取这个服务从缓存中取的次数,这个就可以很容易看出来缓存价值。

 

那么为什么不使用记数器自加呢,例如count++这样的,因为这种计数是线程不安全的,高并发访问时统计会有误,而AtomicInteger为什么能够达到多而不乱,处理高并发应付自如呢,我们才看看AtomicInteger的源代码:

 

 

Java代码  收藏代码
  1. private volatile int value;  

 

 

大家可以看到有这个变量,value就是你设置的自加起始值。注意看它的访问控制符,是volatile,这个就是保证AtomicInteger线程安全的根源,熟悉并发的同学一定知道在java中处理并发主要有两种方式:

1,synchronized关键字,这个大家应当都各种面试和笔试中经常遇到。

2,volatile修饰符的使用,相信这个修饰符大家平时在项目中使用的也不是很多。

 

这里重点说一下volatile:

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存重新读取该成员的值,而且,当成员变量值发生变化时,强迫将变化的值重新写入共享内存,这样两个不同的线程在访问同一个共享变量的值时,始终看到的是同一个值。

 

java语言规范指出:为了获取最佳的运行速度,允许线程保留共享变量的副本,当这个线程进入或者离开同步代码块时,才与共享成员变量进行比对,如果有变化再更新共享成员变量。这样当多个线程同时访问一个共享变量时,可能会存在值不同步的现象。

 

而volatile这个值的作用就是告诉VM:对于这个成员变量不能保存它的副本,要直接与共享成员变量交互。

 

建议:当多个线程同时访问一个共享变量时,可以使用volatile,而当访问的变量已在synchronized代码块中时,不必使用。

缺点:使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用。

分享到:
评论
1 楼 无心流泪wan 2015-08-28  
在多个并发写的情况下使用volatile变量是不安全的!!!!不然也就不会有AtomicInteger了

相关推荐

    AtomicInteger并发测试

    测试java.util.concurrent.atomic.AtomicInteger的类 与直接使用int做区别

    AtomicInteger 浅谈

    NULL 博文链接:https://zcmor.iteye.com/blog/1535524

    Java中对AtomicInteger和int值在多线程下递增操作的测试

    主要介绍了Java中对AtomicInteger和int值在多线程下递增操作的测试,本文得出AtomicInteger操作 与 int操作的效率大致相差在50-80倍上下的结论,需要的朋友可以参考下

    AtomicInteger的使用,CAS的工作原理

    AtomicInteger atomicInteger = new AtomicInteger(5); atomicInteger.compareAndSet(5, 2020) + \t current data is + atomicInteger.get()) /** * Atomically sets the value to the given updated value * if ...

    Java AtomicInteger类的使用方法详解

    主要介绍了Java AtomicInteger类的使用方法详解,文中有具体实例代码,具有一定参考价值,需要的朋友可以了解下。

    Java AtomicInteger类使用方法实例讲解

    主要介绍了Java AtomicInteger类使用方法实例讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java并发之AtomicInteger源码分析

    AtomicInteger是java并发包下面提供的原子类,主要操作的是int类型的整型,通过调用底层Unsafe的CAS等方法实现原子操作。下面小编和大家一起学习一下

    ViewPager+AtomicInteger实现广告轮播

    利用ViewPager实现的广告轮播,没有触摸事件的时候可以定时轮播广告,有触摸事件实施触摸事件。自动轮播使用的是线程加AtomicInteger的方式实现。

    AtomicIntegerExample:AtomicInteger示例

    AtomicInteger示例AtomicInteger用于原子增量计数器之类的应用程序。 简短的示例代码: public class AtomicIntegerExample { private final ExecutorService execService = Executors . newFixedThreadPool( 100 );...

    java线程学习笔记

    2.2 原子性与易变性(volatile) 13 2.2.1 Volatile 13 2.2.2 原子类(AtomicInteger,AtomicLong,AtomicReference) 13 2.3 线程本地存储(Java.lang.ThreadLocal) 15 2.4 线程阻塞 17 2.4.1 调用sleep(millisecond...

    JAVA初级面试题(release)

    NULL 博文链接:https://it-fan.iteye.com/blog/1183175

    Java并发编程相关源码集 包括多任务线程,线程池等.rar

     volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小例子:多个线程竞争问题、多个线程多个锁问题、创建一个缓存的线程池、多线程使用Vector或者HashTable的示例(简单线程同步...

    Redis数据结构与对象总结

    Redis数据结构与对象总结 数据结构与对象 简单动态字符串 SDS简介 SDS与C字符串的区别 常数复杂度获取字符串长度 O(n) O(1) 杜绝缓冲区溢出 修改字符串长度时内存重分配 空间预分配:对字符串进行增长操作时...

    线程基础,线程池,生命周期

    线程基础,线程池,生命周期

    JUC–Atomic原子类

    它还提供了一个原子的 compareAndSet 方法(如果该方法成功执行,那么将实现与读取/写入一个 volatile 变量相同的内存效果),以及原子的添加、递增和递减等方法。AtomicInteger 表面上非常像一个扩

    java多线程自增效率比较及原理解析

    在多线程环境下,对于自增操作需要考虑线程安全问题,常见的解决方法包括使用synchronized关键字、AtomicInteger、LongAdder和LongAccumulator等。本文给出了使用这些方法实现自增的代码演示,并通过多线程测试比较...

    使用Java的Memory Model实现一个简单的计数器.txt

    这个代码实现了一个简单的计数器,使用了Java的`AtomicInteger`类来保证多线程环境下的原子性操作。`AtomicInteger`是一个支持原子操作的整数类,它内部使用了CAS(Compare And Swap)算法来实现线程安全的操作。在...

    java 分页、批量删除

    包含了jsp的简单分页,有首页、尾页、上下页、设置页面数字等,有完整的注释、包、ppt等,mysql数据库的,对后台管理的删除有不错的参考价值,非常适合web初学者,改改就可以在多少场合运用。

    用Java代码所写的简单计数器

    用Java代码所写的简单计数器,功能:根据选票人投票,最后记录数据并用立方图显示结果

    java多线程安全性基础介绍.pptx

    volatile 仅保证可见性 作用 不会被缓存在寄存器或其他对cpu不可见的地方 强制其他线程读主内存 编译器和运行时不会讲该变量的操作与其他内存操作一起重排序 锁不仅保证原子性还保证可见性 有序性 多个线程...

Global site tag (gtag.js) - Google Analytics