AtomicReference和AtomicStampedReference
一、AtomicReference
通过volatile和Unsafe提供的CAS函数实现原子操作。 自旋+CAS的无锁操作保证共享变量的线程安全
- value是volatile类型,这保证了:当某线程修改value的值时,其他线程看到的value的值都是最新的值,即修改之后的volatile的值
- 通过CAS设置value。这保证了:某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作时原子性的,即线程在操作vu略时不会被中断。
但是CAS操作可能存在ABA问题。AtomicStampedReference的出现就是为了解决这问题
备注:ABA问题:原始值为A,某个线程修改为B,另一个线程又修改为A,当第三个线程访问时,获取的值依然是A,认为该值没有被修改过。
注意:如下代码是线程不安全的
//先获取原始值
Integer oldValue = atomicReference.get();
//根据原始值比较进行修改
atomicReference.compareAndSet(oldValue,oldValue+);
若要保证线程安全,需要加锁(Lock或者synchronized)
Lock lock = new ReentrantLock();
...
lock.lock();
Integer oldValue = atomicReference.get();
atomicReference.compareAndSet(oldValue,oldValue+);
lock.unlock();
也就是说对于AtomicXX类,单个方法是原子性的,但是同时调用多个方法则不是原子性的,需要加锁实现线程安全。
二、AtomicStampedReference
AtomicStampedReference它内部不仅维护了对象值,还维护了一个时间戳(我这里把它称为时间戳,实际上它可以是任何一个整数,它使用整数来表示状态值)。当AtomicStampedReference对应的数值被修改时,除了更新数据本身外,还必须要更新时间戳。当AtomicStampedReference设置对象值时,对象值以及时间戳都必须满足期望值,写入才会成功。因此,即使对象值被反复读写,写回原值,只要时间戳发生变化,就能防止不恰当的写入。
举个栗子
AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference(0,1);
lock.lock();
Integer oldValue = atomicStampedReference.getReference();//
int stamp = atomicStampedReference.getStamp();//
atomicStampedReference.compareAndSet(oldValue,oldValue+1, stamp,stamp+1);
lock.unlock();
System.out.println(atomicStampedReference.getReference());//
System.out.println(atomicStampedReference.getStamp());//
AtomicReference和AtomicStampedReference的更多相关文章
- AtomicReference,AtomicStampedReference与AtomicMarkableReference的区别
AtomicReference 通过volatile和Unsafe提供的CAS函数实现原子操作. 自旋+CAS的无锁操作保证共享变量的线程安全 value是volatile类型,这保证了:当某线程修改 ...
- 4.4.4 无锁的对象引用:AtomicReference和AtomicStampedReference
AtomicReference 这个类和AtomicInteger非常类似,只是AtomicReference对应普通的对象引用,而AtomicInteger 它是对整数的封装,它的方法如下 对wea ...
- AtomicReference、AtomicStampedReference 和 AtomicMarkableReference
这三个都是自 JDK1.5 开始加入到 java.util.concurrent.atomic 下面的.他们都可以在 lock-free 的情况下以原子的方式更新对象引用. 一.AtomicRefer ...
- CAS导致的ABA问题及解决:时间戳原子引用AtomicReference、AtomicStampedReference
1.CAS导致ABA问题: CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并交换,那么在这个时间差中会导致数据的变化. 比如:线程1从内存位置V中取出A,这时线程2也从V中取出A ...
- Java中Atomic包的实现原理及应用
1. 同步问题的提出 假设我们使用一个双核处理器执行A和B两个线程,核1执行A线程,而核2执行B线程,这两个线程现在都要对名为obj的对象的成员变量i进行加1操作,假设i的初始值为0,理论上两个线程运 ...
- Java多线程:CAS与java.util.concurrent.atomic
锁的几种概念 悲观锁 总是假设最坏的情况,每次获取数据都认为别人会修改,所以拿数据时会上锁,一直到释放锁不允许其他线程修改数据.Java中如synchronized和reentrantLock就是这种 ...
- java多线程(六)线程控制类
1. 多线程控制类 为了保证多线程的三个特性,Java引入了很多线程控制机制,下面介绍其中常用的几种: l ThreadLocal l 原子类 l Lock类 l Volatile关键字 ...
- DLC双端锁,CAS,ABA问题
一.什么是DLC双端锁?有什么用处? 为了解决在多线程模式下,高并发的环境中,唯一确保单例模式只能生成一个实例 多线程环境中,单例模式会因为指令重排和线程竞争的原因会出现多个对象 public cla ...
- 【Java并发工具类】原子类
前言 为保证计数器中count=+1的原子性,我们在前面使用的都是synchronized互斥锁方案,加锁独占访问的方式未免太过霸道,于是我们来介绍另一种解决原子性问题的无锁方案:原子变量.在正式介绍 ...
随机推荐
- leetcode-easy-array-50. Intersection of Two Arrays II
mycode 77.78% class Solution(object): def intersect(self, nums1, nums2): """ :type n ...
- 一、Jmeter启动报错:Could not initialize class org.apache.jmeter.gui.util.MenuFactory
1.下载: plugins-manager.jar 包 2.地址:https://jmeter-plugins.org/install/Install/ 3.将jar包放到lib/ext 4.重启jm ...
- pycharm+PyQt5 开发配置
安装工具:Pycharm-professional-5.0.5.exePyQT5python3.6 1.首先安装Pycharm,破解时输入:http://idea.imsxm.com/ 登录Pytho ...
- leetcode 441.排列硬币(python)
1.题目描述 你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形成完整阶梯行的总行数. n 是一个非负整数,并且在32位有符号整型的范 ...
- CentOS7 nginx安装与卸载
简明清晰,易操作,参照: CentOS7 nginx安装与卸载
- Java与C#不同
1.C#方法定义可以有默认参数,而Java则不支持该方式. C#方法定义 public void ShowMessage(string text,string orderId="" ...
- iptables规则
iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分 iptables文件设置路径:命令:vim /etc/sysconfig/iptables-config 0x02 ...
- 操作Json对象的C#方法
json对象长这样 { "UniqueName": { "Required": "true", , , "Regex": ...
- js for 循环
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- HttpURLConnection 发送http请求帮助类
java 利用HttpURLConnection 发送http请求 提供GET / POST /上传文件/下载文件 功能 import java.io.*; import java.net.*; im ...