原子引用(AtomicReference)

本文介绍了Java并发编程中三个重要的原子类:AtomicReference、AtomicStampedReference和AtomicMarkableReference。AtomicReference用于实现乐观锁,避免线程上下文切换。AtomicStampedReference增加了时间戳,可以跟踪变化次数。AtomicMarkableReference关注是否发生过变化,而不记录次数。通过示例代码展示了它们在多线程环境中的使用和比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值