原子地更新某个类里的某个字段时,就需要使用原子更新字段类,Atomic包提供了以下4个类进行原子字段更新 AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference、AtomicReferenceFieldUpdater
使用上述类的时候,必须遵循以下原则
字段必须是volatile类型的,在线程之间共享变量时保证立即可见
字段的描述类型是与调用者与操作对象字段的关系一致。
也就是说调用者能够直接操作对象字段,那么就可以反射进行原子操作。
对于父类的字段,子类是不能直接操作的,尽管子类可以访问父类的字段。
只能是实例变量,不能是类变量,也就是说不能加static关键字。
只能是可修改变量,不能使final变量,因为final的语义就是不可修改。
对于AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long类型的字段,不能修改其包装类型(Integer/Long)。
如果要修改包装类型就需要使用AtomicReferenceFieldUpdater。
package com.xdclass.atomic.demo3; import java.util.concurrent.atomic.AtomicLongFieldUpdater; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; public class AtomicLongFieldUpdaterDemo { public static void main(String[] args) { AtomicLongFieldUpdater<Student> longFieldUpdater = AtomicLongFieldUpdater.newUpdater(Student.class, "id"); Student xdclass = new Student(1L, "xdclass"); longFieldUpdater.compareAndSet(xdclass, 1L, 100L); System.out.println("id="+xdclass.getId()); AtomicReferenceFieldUpdater<Student, String> referenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Student.class, String.class, "name"); referenceFieldUpdater.compareAndSet(xdclass, "xdclass", "zssz"); System.out.println("name="+xdclass.getName()); } } class Student{ volatile long id; volatile String name; public Student(Long id,String name){ this.id= id; this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }