【Java并发】Java中的原子操作类
综述
JDK从1.5开始提供了java.util.concurrent.atomic包。
通过包中的原子操作类能够线程安全地更新一个变量。
包含4种类型的原子更新方式:基本类型、数组、引用、对象中字段更新。
atomic包中的原子操作类基本上内部都是使用Unsafe类实现的,原子更新的实质其实就是获取内存偏移地址,对地址中的变量进行更新。
关于Unsafe类,可以参考我的这篇博文【Java并发】Java中的Unsafe类
1.原子更新基本类型类
atomic包内包含AtomicBoolean、AtomicInteger、AtomicLong这3个类,以下以AtomicInteger进行讲解。
AtomicInteger是如何实现原子操作的?
是使用Unsafe类实现的,而Unsafe实现原子操作的原理是通过得到变量相对于对象示例的内存偏移地址,更新内存地址内的变量值。
下面是摘录的AtomicInteger的部分源码。
- /**
- * Atomically increments by one the current value.
- *
- * @return the previous value
- */
- public final int getAndIncrement() {
- return unsafe.getAndAddInt(this, valueOffset, 1);
- }
- /**
- * Atomically decrements by one the current value.
- *
- * @return the previous value
- */
- public final int getAndDecrement() {
- return unsafe.getAndAddInt(this, valueOffset, -1);
- }
- /**
- * Atomically adds the given value to the current value.
- *
- * @param delta the value to add
- * @return the previous value
- */
- public final int getAndAdd(int delta) {
- return unsafe.getAndAddInt(this, valueOffset, delta);
- }
- /**
- * Atomically increments by one the current value.
- *
- * @return the updated value
- */
- public final int incrementAndGet() {
- return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
- }
- /**
- * Atomically decrements by one the current value.
- *
- * @return the updated value
- */
- public final int decrementAndGet() {
- return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
- }
- /**
- * Atomically adds the given value to the current value.
- *
- * @param delta the value to add
- * @return the updated value
- */
- public final int addAndGet(int delta) {
- return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
- }
2.原子更新数组
atomic包内包含AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray这3个类,以下以AtomicIntegerArray进行讲解。
AtomicIntegerArray是如何实现原子操作的?
是使用Unsafe类实现的,而Unsafe实现原子操作的原理是通过得到变量相对于数组的内存偏移地址,更新内存地址内的变量值。
下面是摘录的AtomicIntegerArray的部分源码。
- /**
- * Atomically increments by one the element at index {@code i}.
- *
- * @param i the index
- * @return the previous value
- */
- public final int getAndIncrement(int i) {
- return getAndAdd(i, 1);
- }
- /**
- * Atomically decrements by one the element at index {@code i}.
- *
- * @param i the index
- * @return the previous value
- */
- public final int getAndDecrement(int i) {
- return getAndAdd(i, -1);
- }
- /**
- * Atomically adds the given value to the element at index {@code i}.
- *
- * @param i the index
- * @param delta the value to add
- * @return the previous value
- */
- public final int getAndAdd(int i, int delta) {
- return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
- }
- /**
- * Atomically increments by one the element at index {@code i}.
- *
- * @param i the index
- * @return the updated value
- */
- public final int incrementAndGet(int i) {
- return getAndAdd(i, 1) + 1;
- }
- /**
- * Atomically decrements by one the element at index {@code i}.
- *
- * @param i the index
- * @return the updated value
- */
- public final int decrementAndGet(int i) {
- return getAndAdd(i, -1) - 1;
- }
- /**
- * Atomically adds the given value to the element at index {@code i}.
- *
- * @param i the index
- * @param delta the value to add
- * @return the updated value
- */
- public final int addAndGet(int i, int delta) {
- return getAndAdd(i, delta) + delta;
- }
3.原子更新引用
使用AtomicInteger只能原子更新一个变量,如果要原子更新多个变量,就需要将多个变量封装起来,原子更新对象引用。
atomic包内包含AtomicReference、AtomicReferenceFieldUpdater、AtomicUpdater这3个类,以下以AtomicIntegerArray进行讲解。
下面是摘录的AtomicReference的部分源码。
- /**
- * Atomically sets the value to the given updated value
- * if the current value {@code ==} the expected value.
- * @param expect the expected value
- * @param update the new value
- * @return {@code true} if successful. False return indicates that
- * the actual value was not equal to the expected value.
- */
- public final boolean compareAndSet(V expect, V update) {
- return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
- }
- /**
- * Atomically sets to the given value and returns the old value.
- *
- * @param newValue the new value
- * @return the previous value
- */
- @SuppressWarnings("unchecked")
- public final V getAndSet(V newValue) {
- return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
- }
4.原子更新字段类
用于更新类里的某个字段。
atomic包内包含AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference这3个类。
AtomicStampedReference 将整数值与引用关联起来,可以用于原子地更新数据和数据的版本号,可以解决CAS的ABA问题。
【Java并发】Java中的原子操作类的更多相关文章
- Java中的原子操作类
转载: <ava并发编程的艺术>第7章 当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可 ...
- java并发编程:线程安全管理类--原子操作类--AtomicInteger
在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger
- java中的原子操作类AtomicInteger及其实现原理
/** * 一,AtomicInteger 是如何实现原子操作的呢? * * 我们先来看一下getAndIncrement的源代码: * public final int getAndIncremen ...
- Java并发编程系列-(3) 原子操作与CAS
3. 原子操作与CAS 3.1 原子操作 所谓原子操作是指不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何context switch,也就是切换到另一个线程. 为了实 ...
- Java并发编程中的若干核心技术,向高手进阶!
来源:http://www.jianshu.com/p/5f499f8212e7 引言 本文试图从一个更高的视角来总结Java语言中的并发编程内容,希望阅读完本文之后,可以收获一些内容,至少应该知道在 ...
- Java并发编程中的相关注解
引自:http://www.cnblogs.com/phoebus0501/archive/2011/02/21/1960077.html Java并发编程中,用到了一些专门为并发编程准备的 Anno ...
- Java并发编程中的设计模式解析(二)一个单例的七种写法
Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...
- Java并发编程中线程池源码分析及使用
当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...
- int是java.lang包中可用的类的名称
int是java.lang包中可用的类的名称(x) int为基本数据类型,不是类
随机推荐
- (推荐JsonConvert )序列化和反序列化Json
在Json文本和.Net对象之间转换最快的方法是试用JsonSerializer. JsonSerializer通过将.Net对象属性名称映射到Json属性名称,并为其复制值,将.Net对象转换为其J ...
- 会话技术Cookie&Session
1.会话技术概述 从打开浏览器访问某个站点,到关闭这个浏览器的整个过程,称为一次会话.会话技术用于记录本次会话中客户端的状态与数据. 会话技术分为Cookie和Session: Cookie:数据存储 ...
- ios APP 在 waiting for review时重新上传程序
今天上传程序后发现了一个挺大的bug,想重新上传app,于是搜了一下,现记录一下: 点击details进入后在link点击binary details,进入之后点击右上角reject this bin ...
- JavaWeb中文乱码问题解决思路
1.提交页面请求或者服务器端的响应时,需要确保页面编码当时与服务器编码方式是否一致. 2.对于从服务器写入数据库中的数据和从数据库中读取到服务器中的数据,需要确保服务器编码方式与数据库编码方式是否一致 ...
- Android编译系统入门(一)
做过Android平台开发的朋友对make,mm或make clean命令应该很熟悉,但也许大家只是熟知这些命令的作用却不知道这些命令底下有些什么原理?那么今天我就带着大家推开Android编译系统的 ...
- mysql 中调用存储过程之后,连接断开不可用
解决方法: 由 mysql_real_connect(&m_mysql,host,user,passwd,Db,0,NULL,0) == NULL 改为 mysql_real_connect( ...
- Advanced Bash-Scripting Guide(学习笔记)
http://www.tldp.org/LDP/abs/html/index.html 11.1. Loops tp://www.tldp.org/LDP/abs/html/loops1. ...
- python基础之类的isinstance与issubclass、反射
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo: pass o ...
- Python位运算符
按位运算符是把数字看作二进制来进行计算的.Python中的按位运算法则如下: 下表中变量 a 为 60,b 为 13,二进制格式如下: a = 0011 1100 b = 0000 1101 ---- ...
- python imageio 图片生成gif
#!/bin/python3 import matplotlib.pyplot as plt import imageio,os TIME_GAP=0.075 #两帧之间的时间间隔,秒为单位 FILE ...