Java|伙计,提高自己的并发技能,从锁优化开始!( 四 )
CAS操作一个变量时 , 只有一个会胜出 , 并成功更新 , 其他均会失败 。 失败的线程不会被挂起 , 仅是被告知失败 , 并且允许再次尝试 , 当然也允许失败的线程放弃操作 。
线程安全整数(AtomicInteger)AtomicInteger是在 JDK并发包中的atomic 中的 , 可以把它看作一个整数 , 与Integer不同的是 , 它是可变的 , 并且是线程安全的 。 对其进行修改等任何操作都是用 CAS 指令进行的 。 下面是AtomicInteger 的常用方法:
就内部实现上来说 , AtomicInteger中保存了一个核心字段:
使用示例:可以看出 , 在多线程的情况下 , AtomicInteger是保证线程安全的 。
无锁的对象引用(AtomicReference)AtomicReference 和AtomicInteger非常相似 , 不同之处就在于AtomicInteger是对整数的封装 , 而AtomicReference是对普通对象的引用 , 也就是它可以保证你在修改对象引用时的线程安全性 。
通常情况下线程判断被修改对象是否可以正确写入的条件是对象的当前值和期望值是否一致是正确的 。 但是有一种特殊的情况就是:当你获取对象当前数据后 , 在准备修改被新值前 , 对象的值被其他线程连续修改了两次 , 最后一次修改为旧值 , 这个时候线程在不知情的情况下 , 又对这个数据重新赋值 。 下图说明为例:
带有时间戳的对象引用(AtomicStampedReference)AtomicReference无法解决上面的问题是因为 , 对象在修改成成中丢失了状态信息 , 因此我们只要能够记录对象在修改过程中的状态值 , 就可以很好的解决对象被反复修改的导致线程无法正确判断对象状态的问题 。
AtomicStampedReference它内部不经维护了对象值 , 还维护了一个时间戳 , 当AtomicStampedReference被修改的时候 , 除了更新数据本身外 , 还必须要更新时间戳 。 当AtomicStampedReference设置对象值时 , 对象值及时间戳都必须满足期望值 , 写入才会成功 , 因此 , 即使对象之被反复读写 , 写回原值 , 只要时间戳发生变化 , 就不能正确写入 。
推荐阅读
- Java|计算机专业的本科生,该选择学习Java技术体系还是.NET技术体系
- 挖贝网|销量大幅提高,色如丹2020年上半年净利1202.76万增长47.77%
- 小熊回收站|-链表阻塞队列和数组阻塞队列的异同,Java并发编程
- Java|马化腾登顶中国首富,微信、QQ却都免费使用,腾讯到底咋赚钱的?
- Java|为什么美团骑手总是闯红灯昵
- ifory安福瑞|整体信号提高2倍以上,手机信号不好?教你4个方法
- 手艺人兴哥|运行速度虽然会更快,但用户不太容易感知,手机性能提高10倍
- 阿里巴巴|java三大集合遍历方法
- 编程|JAVA基础-网络编程
- Java|Java中的天使和魔鬼:Unsafe类
