原子引用
大约 1 分钟Juc
为什么需要原子引用类型
当我们需要保护的数据为一个对象引用,而不是基本数据类型时
注意原子引用类型只能保证对象引用的安全,而不能保证对象属性的线程安全,对象属性的线程安全仍然需要程序员自己保证,除非这个类是不可变类,你做了更改就会创建一个新的对象,返回新的引用,这样原子引用类就可以检测到
原子引用类型
- AtomicReference
- AtomicMarkableReference
- AtomicStampedReference
CAS只有线程数小于cpu核心数时才能起到提升效率的效果
AtomicReference
创建:
AtomicReference<BigDecimal> balance new AtomicReference<BigDecimal>();使用:
while(true){
//AtomicReference的get()方法获取包装在引用中的值
BigDecimal prev=balance.get();
BigDecimal next=prev.substract(amount);
//AtomicReference的compareAndSet()方法使用cas判断引用值是否相同
if(balance.compareAndSet(prev,next)){
break;
}
}AtomicStampedReference
通过添加版本号的方式解决ABA问题
使用方式:
创建:
//这里在创建的时候还要添加一个版本号,用来表示修改次数
AtomicStampedReference<String> s=new AtomicStampedReference<String>("stamped",0);使用:
//获取原子引用
s.getReference();
//获取版本号
s.getStamp();
//在进行CAS操作时,还要添加对版本号的判断
s.compareAndSet("prev","next",0,1);AtomicMarkableRefe
这个原子引用类不关心我的版本变了几次,而是只关心引用变没变
创建:
//在创建的时候要指定一个布尔值
AtomicMarkableReference<String> bag=new AtomicMarkableReference<String>("bag",true);使用:
//在对比的时候加上布尔值
s.compareAndSet("prev","next",false,true);