Atomic 包中的类提供了对数据进行原子操作的功能。
例如
a++ 、a+=1等类似代码不是原子的,实现过程是由内存中取出数据,对数据进行计算,再结果写入内存,属于复合操作,由多条CPU指令完成。 在单线程下这些代码会运行良好,如果a是多线程中的共享变量,那么运行结果可能会不正确。
举列: a表示一个累计值,以a++为例:
X线程 从内存中取出a的值=5,执行a++,得出的结果是6,并未写回内存时前,Y线程从内存中取出a的值=5,X线程将a=6写回内存,但Y缓存中a的值=5,执行a++得出结果为6,写回内存a=6。 结果是两个线程分别对5进行加1操作,但结果等于6,累计值就少了1。
避免这种情况产生,可以采用如下方式:
1.采用 synchronized或 ReentrainLock锁 ,某一时刻只能有一条线程对a操作,即线程互斥。(阻塞方式)
2.采有原子类操作,将a定义为AtomicInteger或AtomicLong ,调用incrementAndGet方法加1. (非阻塞方式)
AtomicLong中的 incrementAndGet源码分析如下:
private volatile long value;//long数据值 标记为 volatile 每次读取写入值在主内存中操作,而不是线程的缓存中,使值的变化其它线程立即可见。 private static final Unsafe unsafe = Unsafe.getUnsafe(); //Unsafe 用于实现CAS(compare and swap) 操作,基于CPU一条原始指令,是原子的线程安全的,可用于多线程间非阻塞方式实现线程安全。 static { try { valueOffset = unsafe.objectFieldOffset (AtomicLong.class.getDeclaredField("value"));//value值在内存中的偏移地址,用于直接修改内存值 } catch (Exception ex) { throw new Error(ex); } } public final long getAndIncrement() { while (true) {//在循环中设定value的值,直至成功。 long current = get();//取出主内存中的value值存入线程栈 long next = current + 1;//线程栈中的value值+1 if (compareAndSet(current, next))//原子的设定value值,如果返回值是假,说明当前主内存中的实际值与线程栈中的值不相等,可能其它线程修改了内存中值,需要基于新值再次计算,即又一次循环 return current; } } /** *原子的操作方法, * 如果expect(期望值)与value实际相等,说明数据没有被改过,就用update(新值)替换实际值并反回真,执行过程是原子的,线程安全, * 如果expect(期望值)与value实际相等,说明数据可能被改过,返回假。 * */ public final boolean compareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); }
java.util.concurrent.atomic 原子更新的包 包含:AtomicBoolean --原子的更新boolean值 AtomicInteger --原子的更新integer值 AtomicLong --原子的更新long值 AtomicLongArray --原子的更新long数组 AtomicIntegerArray --原子的更新int数组 AtomicReference --原子的更新一个对象引用 AtomicReferenceFieldUpdater --原子的更新一个类实例中属性的引用 AtomicIntegerFieldUpdater --原子的更新一个类实例中int属性值 AtomicLongFieldUpdater --原子的更新一个类实例中long属性值 这些类基于unsafe类,使用cas方法和 volatile 来保证原子操作: 1,Unsafe类提供了硬件级别的原子操作,cas(compare and swap) 基于比较交换的方式(当前值相等的情况下,再设置新值),使用的方式 2. volatile 保证了内存的可见性。 /** * * 当前值+1,并返回当前值,原子的 * */ public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } /** * 通过cas方式,不断循环设置新值,直到成功,返回旧值。 * */ public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }
相关推荐
Atomic
Atom-Atomic-Monokai-Syntax.zip,A Monokai-flavored syntax highlighting theme for Atom作为一个长期的优秀文本用户,我已经过渡到使用atom作为我的代码编辑器,虽然我喜欢它更易破解的方面,但我并没有找不到一个...
Atomic Alarm Clock是 Clock Tray Skins 的同胞软件,具有 Clock Tray Skins 的全部功能,可以替换美化并增强系统自带的任务栏时钟,显示的时间更加仔细,包含月、日、星期、时、分与秒及日历显示、时区等,界面漂亮...
主要研究四种变量(属性)的存取速度. volatile nonatomic atomic和正常变量
来自BOOST库的原子操作atomic的源代码,跨平台
atomic_ops原子操作1
《Docker容器 利用Kubernates Flannel Cockpit和Atomic构建和部署》
前端开源库-atomic-batcher原子批处理程序,一个简单的批处理函数,允许您自动批处理一系列操作。
不错的时钟工具,带闹铃,日历,可置顶 Atomic Alarm Clock.rar
systemd-208-99.atomic.0.el7.x86_64.rpm
ATOMIC:an atlas of machine commonsense for if-then reasoning中的数据集
ZooKeeper’s atomic broadcast protocol 翻译版
Atom-atomic-blonde.zip,SourceKit-based syntax highlighting for the Swift languageAtomic Blonde是一种基于SourceKit的用于Swift语言的语法增强器。与由正则表达式语法支持的highlighter不同,atomic blonde调用...
angular-atomic-notify, angular.js 应用程序的原子咆哮通知 angular-atomic-notify一个用于显示通知的AngularJS模块 依赖项我们使用这个库作为示例,注意jQuery用于 angular.element 和 Font Awesome 图标,但是你...
Introduction to quantum optics and modern atomic physics. The basic concepts and theoretical tools will be introduced. Topics will include coherence phenomena, non-classical states of light and matter...
Atomic CSS增量更新的设计与实现,刘灿,沈奇威,(1)针对Atomic CSS全量更新过程中耗费时间、流量较大的问题,提出一种增量更新方案。该方案将CSS内容与版本信息分别保存于浏览器Loca
资源来自pypi官网。 资源全名:atomic-queue-1.0.1.tar.gz
Problems And Solutions On Atomic, Nuclear, And Particle Physics Problems And Solutions On Atomic, Nuclear, And Particle Physics Problems And Solutions On Atomic, Nuclear, And Particle Physics
dll控件常规安装方法(仅供参考): 一、如果在运行某软件或编译程序时提示缺少、找不到dll等类似提示,您可将下载来的dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或者重新添加文件引用...