AtomicReference、AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater等类的使用

释放双眼,带上耳机,听听看~!

AtomicReference类的作用是以原子的方式更新引用类型。下面我们看一下具体的例子。

/**
 * 用户登录
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:35
 * @since 1.0.0
 */
public class Userinfo {

    private String username;
    private String password;

    public Userinfo(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public Userinfo() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
/**
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 13:35
 * @since 1.0.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        AtomicReference<Userinfo> atomic = new AtomicReference<Userinfo>();
        Userinfo userinfo = new Userinfo("admin", "administrator");
        atomic.set(userinfo);
        Userinfo update = new Userinfo("user", "123456");
        System.out.println(String.format("%s	%s", atomic.get().getUsername(), atomic.get().getPassword()));
        atomic.compareAndSet(userinfo, update);
        System.out.println(String.format("%s	%s", atomic.get().getUsername(), atomic.get().getPassword()));
    }
}
admin	administrator
user	123456

下面我们看一下AtomicReferenceFieldUpdater类的使用,我们有时不想更新对象的所有属性,只想更新某一个字段,并且我们知道字段的返回值类型也有可能是不确定的,所以Java并发工具包里为我们提供了很多字段的更新类型。如AtomicIntegerFieldUpdater类和AtomicLongFieldUpdater类,前者就是更新Integer类型的字段后者就是更新Long类型字段的。除此之外我们还知道字段的类型还可能是引用类型,那我们就可以用AtomicReferenceFieldUpdater类来更新某一个引用类型的字段,这几个更新字段的类的使用方法几乎一样,所以下面只演示AtomicReferenceFieldUpdater类的使用,并且用String类型来演示。

/**
 * 用户登录
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:35
 * @since 1.0.0
 */
public class Userinfo {

    public volatile String username;
    private String password;

    public Userinfo(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public Userinfo() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
/**
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 13:35
 * @since 1.0.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        AtomicReferenceFieldUpdater<Userinfo, String> atomic = AtomicReferenceFieldUpdater.newUpdater(Userinfo.class, String.class, "username");
        Userinfo userinfo = new Userinfo("admin", "administrator");
        System.out.println(atomic.get(userinfo));
        System.out.println(atomic.compareAndSet(userinfo, "admin", "管理员"));
        System.out.println(atomic.get(userinfo));
    }
}
admin
true
管理员

这里有二点要注意:

  • 更新的实例变量必须是volatile变量否则更新时会出异常。
Exception in thread "main" java.lang.IllegalArgumentException: Must be volatile type
	at java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:228)
	at java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdater.java:95)
	at Test.main(Test.java:13)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
  • 更新的实例变量必须是public变量否则更新时会出异常。
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalAccessException: Class Test can not access a member of class Userinfo with modifiers "private"
	at java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.<init>(AtomicIntegerFieldUpdater.java:284)
	at java.util.concurrent.atomic.AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdater.java:76)
	at Test.main(Test.java:11)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalAccessException: Class Test can not access a member of class Userinfo with modifiers "private"
	at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:109)
	at sun.reflect.misc.ReflectUtil.ensureMemberAccess(ReflectUtil.java:103)
	at java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.<init>(AtomicIntegerFieldUpdater.java:280)
	... 7 more

下面我们看一下AtomicIntegerFieldUpdater类的使用,它比AtomicReferenceFieldUpdater类简单了一点。

public class Userinfo {

    public String username;
    private String password;
    public volatile int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Userinfo(String username, String password, int age) {
        this.username = username;
        this.password = password;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Test {
    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerFieldUpdater<Userinfo> atomic = AtomicIntegerFieldUpdater.newUpdater(Userinfo.class, "age");
        Userinfo userinfo = new Userinfo("admin", "administrator", 17);
        System.out.println(atomic.get(userinfo));
        atomic.getAndIncrement(userinfo);
        atomic.weakCompareAndSet(userinfo,18, 20);
        System.out.println(atomic.get(userinfo));
    }
}
17
20
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧