【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为基本数据类型,不是类
随机推荐
- double类型转化成string
public static void main(String[] args) { double priceWithFreight = 1200.5698d; System.out.println(pr ...
- Ruby on Rails 初次冲浪体验
为了更好的阅读体验,欢迎訪问 作者博客原文 Rails is a web application development framework written in the Ruby language. ...
- Windows查看网络端口被占用情况netstat命令
在windows命令行窗口下执行: C:\>netstat -aon|findstr "80" TCP 127.0.0.1:80 0.0.0.0:0 ...
- wireshark抓取OpenFlow数据包
在写SDN控制器应用或者改写控制器源码的时候,经常需要抓包,验证网络功能,以及流表的执行结果等等,wireshark是个很好的抓包分析包的网络工具,下面简介如何用wireshark软件抓取OpenFl ...
- java的static final和final的区别
转自:https://www.cnblogs.com/EasonJim/p/7841990.html 说明:不一定准确,但是最快理解. final: final可以修饰:属性,方法,类,局部变量(方法 ...
- 170215、监听器(HttpSessionListener)在开发中的应用
这个监听器主要用于网站在线超时退出的功能. OnlineUserListener实现了HttpSessionListener定义的两个方法: sessionCreated()和sessionDestr ...
- apache (web服务器) ->php->mysql,xampp与wamp比较,WAMP与WNMP有什么区别
wamp环境 1.W:windows 2.A:APACHE 3.M:mysql 4. p:php wnmp环境 1.W:windows 2.A:APACHE 3.n nginx 4. p:php WA ...
- kafka_2.11-0.10.1.1集群搭建安装配置
在搭建kafka集群之前,请保证zookeeper已安装. 1.下载 官网下载链接:http://mirrors.tuna.tsinghua.edu.cn/apache/kafka/0.10.1.1/ ...
- 找不到ifconfig命令
对于新安装的系统,可能会缺少ifconfig命令,这是因为少安装了net-tools工具,所以只要安装上即可. yum install net-tools -y
- fun_action
make an absolute URI from a relative one http://php.net/manual/en/function.header.php <?php /* Re ...