在有些情况下,需要保证对一个类中的属性的变量访问的线程安全性,就需要用到
AtomicReferenceFieldUpdater
,AtomicLongFieldUpdater
,AtomicIntegerFieldUpdater
等属性原子更新器。
代码示例:以AtomicReferenceFieldUpdater
为例子
AtomicReferenceFieldUpdater updater = AtomicReferenceFieldUpdater
.newUpdater(Student.class, String.class, "username");
Student stu = new Student();
String username = stu.getUsername();
// 这个线程先运行, 更新成功,因为起初内存里面是null
new Thread(() -> {
String username1 = stu.getUsername();
System.out.println(updater.compareAndSet(stu, username1, "李四"));
System.out.println(stu);
},"t1").start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 主线程后运行,内存里面已经被改成了"李四",和expect不一致,因此改不成功
System.out.println(updater.compareAndSet(stu, username, "张三"));
System.out.println(stu);
}
static class Student {
public String getUsername() {
return username;
}
volatile String username;
@Override
public String toString() {
return "student{" +
"username='" + username + '\'' +
'}';
}
}
说明:本质上还是用了cas的思想,也就是当前线程的工作内存中的属性值和主存中的值一致,那么就代表可以更新,否则不能更新
运行结果:
文章评论