java原子操作类-基本类型类
2016-07-03 22:39
471 查看
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2。因为A和B线程在更新变量i之前拿到i的值都是1,这就是线程不安全的更新操作,通常我们可以采用synchronized来解决这个问题,但是效率比较低。
而java从1.5之后提供了atomic包,这个包中的原子操作类提供了一种用法简单、性能高效、线程安全的更新一个变量的方式。
因为变量的类型有很多种,所以在atomic包里提供了13个类,属于4种类型的原子更新方式,分别是原子更新基本类型、原子更新数组、原子更新引用和原子更新属性。atomic包里的类基本都是使用Unsafe实现的包装类。
使用原子的方式更新基本类型,atomic包提供了3个类:
AtomicBoolean:原子更新布尔类型
AtomicInteger:原子更新整型
AtomicLong:原子更新长整型
3个类的提供的方法基本一致,AtomicInteger主要方法如下
int addAndGet(int delta);//以原子方式将输入的数值与实例中的值相加并返回结果
boolean compareAndSet(int expect,int update);//如果输入的数值等于预期值,则以原子方式将该值设置为输入的值
int getAndIncrement();//以原子方式将当前值加1,然后返回自增前的值
void lazySet(int newValue);//最终会设置成newValue,使用lazeSet设置值后,可能导致其他线程在之后的一小段时间内还是可以读取到旧值。
int getAndSet(int newValue);//以原子方式设置为newValue的值,并返回旧值
AtomicInteger是如何实现原子操作的呢?请看源码如下
unsafe中一直循环修改变量的值,直到修改成功.
而java从1.5之后提供了atomic包,这个包中的原子操作类提供了一种用法简单、性能高效、线程安全的更新一个变量的方式。
因为变量的类型有很多种,所以在atomic包里提供了13个类,属于4种类型的原子更新方式,分别是原子更新基本类型、原子更新数组、原子更新引用和原子更新属性。atomic包里的类基本都是使用Unsafe实现的包装类。
使用原子的方式更新基本类型,atomic包提供了3个类:
AtomicBoolean:原子更新布尔类型
AtomicInteger:原子更新整型
AtomicLong:原子更新长整型
3个类的提供的方法基本一致,AtomicInteger主要方法如下
int addAndGet(int delta);//以原子方式将输入的数值与实例中的值相加并返回结果
boolean compareAndSet(int expect,int update);//如果输入的数值等于预期值,则以原子方式将该值设置为输入的值
int getAndIncrement();//以原子方式将当前值加1,然后返回自增前的值
void lazySet(int newValue);//最终会设置成newValue,使用lazeSet设置值后,可能导致其他线程在之后的一小段时间内还是可以读取到旧值。
int getAndSet(int newValue);//以原子方式设置为newValue的值,并返回旧值
AtomicInteger是如何实现原子操作的呢?请看源码如下
public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); }
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; }
unsafe中一直循环修改变量的值,直到修改成功.
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- nginx代理指定目录
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- 访问Nginx发生SSL connection error的一种情况
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序