AtomicStampedReference 与 AtomicInteger
来源:互联网 发布:淘宝网新店怎么推广 编辑:程序博客网 时间:2024/06/05 23:02
如题两个类均为原子操作,是线程安全的
对于ABA的问题,由于普通的CAS在进行比较的时候是拿一个值和期望值进行比较是否一样,如果一样的话会做替换复制操作,不一样不会进行替换赋值操作。但是在使用中如果一个值被多个线程更改由A变成B在由B变成A,如果单纯去比较值的话CAS是可以通过的,但是对于一些的含有过程的业务场景来说这个是有问题,所以可以使用AtomicStampedReference来处理,它在处理的过程中不仅会比较值还会比较时间戳,这样就保证了真正的唯一相符。
eg:当用户低于20是进行充值,但是用户最多只能充值两次,
public class ThreadAtomicStampedReference { static AtomicStampedReference<Integer> money = new AtomicStampedReference<Integer>(19,0); final static AtomicInteger at = new AtomicInteger(0); public static void main(String[] args) { for(int i=0;i<3;i++){ final Integer stamp=money.getStamp(); new Thread(new Runnable() { @Override public void run() { while(true){ Integer m = money.getReference(); Integer stamp=money.getStamp(); if(m<20&&at.get()<2){ if(money.compareAndSet(m,m+20,stamp,stamp+1)){ System.out.println("余额小于20,充值成功,当前余额:"+money.getReference()); at.getAndIncrement(); } } } } }).start(); } new Thread(new Runnable() { @Override public void run() { while(true){ Integer m = money.getReference(); Integer stamp = money.getStamp(); if(m>10){ System.out.println("金额大于10:"+m); if(money.compareAndSet(m,m-10,stamp,stamp+1)){ System.out.println("成功消费10元,剩余金额:"+money.getReference()); } }else { System.out.println("余额不足10元"); } } } }).start(); }}
余额小于20,充值成功,当前余额:39
金额大于10:39
成功消费10元,剩余金额:29
金额大于10:29
成功消费10元,剩余金额:19
余额小于20,充值成功,当前余额:39
金额大于10:39
成功消费10元,剩余金额:29
金额大于10:29
成功消费10元,剩余金额:19
金额大于10:19
成功消费10元,剩余金额:9
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
余额不足10元
0 0
- AtomicStampedReference 与 AtomicInteger
- AtomicInteger 理论与实践
- AtomicInteger与Volatile修饰
- AtomicInteger用法与原理
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- AtomicInteger
- 关于工作的一点总结和思考
- JS执行顺序
- 解决IScroll5超链接点击无效的问题
- Java 字符与字符串运算
- 通过网页打开App并传递参数
- AtomicStampedReference 与 AtomicInteger
- ReactJS修炼之路(二):组件的key
- MeasureSpec学习 - 转
- 关于/etc/hosts和/etc/resolv.conf以及默认网关的概念学习
- Android 内存抖动 性能分析 <10>
- linux上的asp.net,架构分类整理记录
- ubuntu 安装 mysql php5 apache2 mysql扩展无法安装
- Java 赋值运算符 +=
- 线程安全与重入以及异步信号安全的区别.