1.AtomicReference:原子引用,可以用于乐观锁,避免线程上下文的切换,提升系统的运行效率。相关的“ABA”问题的代码如下:
static AtomicReference<String>ref=new AtomicReference<>("A");
public static void main(String[] args) throws InterruptedException {
System.out.println("start..");
String fist=ref.get();
other();
Thread.sleep(1000);
System.out.println("change A->C:"+ref.compareAndSet("A","C"));
}
public static void other() throws InterruptedException {
new Thread(()->{
System.out.println("change A->B:"+ref.compareAndSet(ref.get(),"B"));
}).start();
Thread.sleep(500);
new Thread(()->{
System.out.println("change B->A:"+ref.compareAndSet(ref.get(),"A"));
}).start();
}
2.AtomicStampReference:可以根据其getStamp()API获取其时间戳,相对于AtomicReference可知其中间发生过几次变化。
@Test
public void testStamped() throws InterruptedException {
AtomicStampedReference<String> reference=new AtomicStampedReference<>("A",0);
String first=reference.getReference();
int version=reference.getStamp();
change(reference);
Thread.sleep(1000);
System.out.println("change A-C:"+reference.compareAndSet("A","C",version,version+1));
}
private static void change( AtomicStampedReference<String> reference) throws InterruptedException {
new Thread(()->{
System.out.println("change A->B:"+reference.compareAndSet(reference.getReference(),"B",reference.getStamp(),reference.getStamp()+1));
}).start();
Thread.sleep(500);
new Thread(()->{
System.out.println("change B->A:"+reference.compareAndSet(reference.getReference(),"B",reference.getStamp(),reference.getStamp()+1));
}).start();
}
3.AtomicMarkableReference:相较于AtomicStampReference无法知道其具体发生几次变化,侧重于判断其中是否发生改变。
@Test
public void MarkableReference() throws InterruptedException {
AtomicMarkableReference<Garbage> reference=new AtomicMarkableReference<Garbage>(new Garbage("垃圾袋已满!"),true);
Garbage garbage=reference.getReference();
boolean flag=reference.isMarked();
System.out.println("change before:"+garbage+","+garbage.getDesc());
alter(reference,garbage);
Thread.sleep(1000);
System.out.println("change:"+reference.compareAndSet(garbage,new Garbage("换垃圾袋"),flag,true));
System.out.println("change after:"+reference.getReference()+","+garbage.getDesc());
}
public static void alter(AtomicMarkableReference<Garbage> reference,Garbage garbage) throws InterruptedException {
Thread t1=new Thread(()->{
garbage.setDesc("垃圾已经倒掉");
System.out.println("Order change:"+reference.compareAndSet(garbage,garbage,reference.isMarked(),false));
});
t1.start();
t1.join();
}
class Garbage{
private String desc;
public Garbage(String desc) {
this.desc = desc;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}