AtomicReference使用场景

1.简介

赋值操作不是线程安全的。若想不用锁来实现,可以用AtomicReference<V>这个类,实现对象引用的原子更新。

使用场景:一个线程使用student对象,另一个线程负责定时读表,更新这个对象。那么就可以用AtomicReference这个类。 

package org.luzhen.test;

public class Student {

    private String name;

    private Integer age;

    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}


package org.luzhen.test;

import java.util.concurrent.atomic.AtomicReference;
 
public class Test
{ 
    public final static AtomicReference<Student> atomicStudent = new AtomicReference<Student>();
    public static void main(String[] args)
    {

        final Student student1 = new Student("a",1);
        final Student student2 = new Student("b",2);

        //初始值为student1对象
        atomicStudent.set(student1);

        for (int i = 0; i < 10; i++)
        {
            new Thread() {
                public void run() {
                    try
                    {
                        //为了 使得控制台打印的 更改student1的线程 能显示出不一样 每个线程随机停顿 多执行几次能看出效果
                        Thread.sleep(Math.abs((int)Math.random()*100));
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                    //预期值 student1和 当前值(上面的atomicStudent.set(student1);)相等时候 赋予student2新的值
                    if (atomicStudent.compareAndSet(student1,student2))
                    {
                        System.out.println(Thread.currentThread().getId() + "Change value");
                        System.out.println(atomicStudent.get().getName()+":"+atomicStudent.get().getAge());
                    }else {
                        System.out.println(Thread.currentThread().getId() + "Failed");
                    }
                };
            }.start();
        }
    }
}

打印结果:执行2次 可以看到 第一次只有线程9 改成功  第二次只有线程8该成功 

9Change value
8Failed
11Failed
12Failed
10Failed
9Change value
14Failed
b:2
13Failed
16Failed
15Failed
17Failed

Process finished with exit code 0

8Change value
12Failed
11Failed
10Failed
9Failed
14Failed
13Failed
b:2
15Failed
16Failed
17Failed

Process finished with exit code 0

二、使用场景

https://www.cnblogs.com/liumy/p/11632878.html

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: AtomicReference使用场景是在多线程环境下,需要对某个对象进行原子性的读取和修改操作时。例如,在一个高并发的系统中,多个线程需要同时对同一个对象进行读取和修改操作,如果不使用原子性的操作,就会出现数据不一致的情况。而使用AtomicReference可以保证对该对象的读取和修改操作是原子性的,从而避免了数据不一致的问题。另外,AtomicReference还可以用于实现一些高级的并发算法,例如无锁算法等。 ### 回答2: AtomicReference是Java中的一个原子类,它可以保证对共享变量的操作在多线程环境下的原子性。在Java并发编程中,AtomicReference使用场景非常广泛,下面是几个常见的使用场景: 1. 作为带有CAS操作的线程安全容器: AtomicReference可以用于存储一个可修改的对象,多个线程可以同时对这个对象进行访问和修改,通过CAS操作可以保证对象值的原子性。 2. 提供线程间的数据传递:如果多个线程需要传递共享的数据,可以将这个数据封装到AtomicReference中,多个线程可以同时访问和修改这个AtomicReference对象。 3. 实现乐观锁:如果需要实现乐观锁,可以使用AtomicReference来存储锁的状态,多个线程可以对这个锁状态进行操作,可以进行CAS操作来保证锁状态的正确性。 4. 实现对象的原子性更新:在Java中,对象本身是不具备原子性的,如果多个线程同时修改同一个对象,会产生数据竞争,容易出现线程安全问题。使用AtomicReference可以将对象存储在其中,并且进行原子性更新,这样就可以保证多个线程对对象的操作是原子的。 5. 实现ABA问题的解决:在多线程环境下,当一个线程将某个值从A改为B,然后再将其从B改回A,此时另一个线程可能认为这个值没有发生变化,出现ABA问题。使用AtomicReference可以通过在更新时增加一个版本号来解决ABA问题。 综上所述,AtomicReference具有广泛的使用场景,在多线程环境下,使用AtomicReference可以保证共享变量的原子性操作,从而提高程序的并发性和线程安全性。 ### 回答3: AtomicReference是Java中的一个原子操作类,底层使用了CAS(Compare And Swap)算法来达到线程安全的目的。 AtomicReference中可以存储任何类型的对象,常用于多个线程之间共享数据。因为多个线程同时访问共享数据可能会导致数据不一致的问题,因此使用AtomicReference可以确保共享数据的线程安全。 AtomicReference使用场景主要包括以下几个方面: 1. 实现多线程计数器 在多线程环境中,如果不使用线程安全的计数器,就可能出现数据不一致的问题。使用AtomicReference可以轻松地实现一个线程安全的计数器。 2. 实现多线程缓存 在多线程环境中,如果多个线程同时访问同一个缓存,就可能会出现数据不一致的问题。使用AtomicReference可以确保多个线程同时访问缓存的线程安全。 3. 实现并发集合 在多线程环境中,如果多个线程同时访问同一集合,就可能会出现数据不一致的问题。使用AtomicReference可以确保多个线程同时访问集合的线程安全。 4. 实现对象的原子更新 在某些场景下,需要对某个对象进行原子更新,此时可以使用AtomicReference来实现。例如,在CyclicBarrier中,需要对一个内部的原始对象进行原子更新以达到线程同步的目的。 总之,AtomicReference是Java中非常实用的一个原子操作类,可以用于确保共享数据的线程安全。其使用场景非常广泛,是Java多线程编程中不可或缺的一部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值