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