当前位置: 首页 > news >正文

AtomicInteger

今天写代码,尝试使用了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优化失去作用,导致效率较低,所以要在必要的时候使用。



本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/6110032.html,如需转载请自行联系原作者

相关文章:

  • silverlight笔记一:创建silverlight应用程序
  • [北京] [在线教育项目] [学而思] 求 PHP 攻城狮 3 枚 ╮(╯_╰)╭
  • 使用NSClassFromString
  • NeHe OpenGL教程 第十一课:飘动的旗帜
  • 上海我的追求
  • Jq-change(fontsize,background)
  • 还原某一个目录下的所有数据库备份文件
  • 全局获取 (Activity)Context,实现全局弹出 Dialog
  • Android 机顶盒手势、数据分页演示DEMO
  • 框架frameset和iframe的区别!
  • 异步CTP(Async CTP)为什么那样工作?
  • 把python文件编译成exe文件
  • ArcGis Mobile根据查询出来的坐标画marker(DrawMapImage)
  • 什么是Heartbeat
  • hdu 4027 Can you answer these queries?
  • [nginx文档翻译系列] 控制nginx
  • 07.Android之多媒体问题
  • CSS实用技巧干货
  • Golang-长连接-状态推送
  • Java方法详解
  • java概述
  • JSDuck 与 AngularJS 融合技巧
  • Just for fun——迅速写完快速排序
  • Promise面试题2实现异步串行执行
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Spring声明式事务管理之一:五大属性分析
  • 不上全站https的网站你们就等着被恶心死吧
  • 看域名解析域名安全对SEO的影响
  • 面试遇到的一些题
  • 前端之React实战:创建跨平台的项目架构
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 为视图添加丝滑的水波纹
  • FaaS 的简单实践
  • hi-nginx-1.3.4编译安装
  • 我们雇佣了一只大猴子...
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​Java并发新构件之Exchanger
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #pragma once
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (BFS)hdoj2377-Bus Pass
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (floyd+补集) poj 3275
  • (NSDate) 时间 (time )比较
  • (二开)Flink 修改源码拓展 SQL 语法
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (转) Face-Resources
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .cfg\.dat\.mak(持续补充)
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .Net MVC + EF搭建学生管理系统
  • .net 流——流的类型体系简单介绍
  • .NET 中什么样的类是可使用 await 异步等待的?