atomic包下几个类的用法

atomic包下几个类的用法

1.原子更新引用类型

以原子的方式更新某个引用对象,可以使用如下的类去实现
AtomicReference
使用过程中,更新的时候要避免错误使用

/**
 * 原子更新整个引用类型
 * @author senninha
 *
 */
public class AtomicReferenceTest {
    public AtomicReference  user = new AtomicReference(null);
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AtomicReferenceTest t = new AtomicReferenceTest();
        t.user.set(new User("senninha","21"));
        User user = t.user.get();
        //错误的更新方法
        user.setAge("10");
        //正确的更新方法
        user = new User("senninha","22");
        t.user.set(user);
    }

}

class User{
    private String username;
    public User(String username, String age) {
        super();
        this.username = username;
        this.age = age;
    }
    public String getUsername() {
        return username;
    }
    public String getAge() {
        return age;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setAge(String age) {
        this.age = age;
    }
    private String age;
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("User [username=");
        builder.append(username);
        builder.append(", age=");
        builder.append(age);
        builder.append("]");
        return builder.toString();
    }
    
}
2.带时间戳的原子更新

避免更新时候出现ABA这样的错误,使用带时间戳的原子更新方式

/**
*
*
**/
public class AtomicStampReferenceTest {
    public AtomicStampedReference user = null;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        User u = new User("senninha","21");
        AtomicStampReferenceTest aft = new AtomicStampReferenceTest();
        //这里可以用时间戳来表示0
        aft.user = new AtomicStampedReference(u, 0);
        u = new User("senninha","22");
        //aft.user.set(u,System.currentTimeMillis());
        aft.user.set(u, aft.user.getStamp() + 1);
        System.out.println(aft.user.getStamp() + " " + aft.user.getReference());
    }

}

3.原子更新类中某个字段

如1那里,其实要更新的只是age字段,就可以使用原子更新某个字段的方法
AtomicIntegerFieldUpdater
AtomicLongFieldUpdater
AtomicReferenceFieldUpdater
需要把他们声明为public volatile类型

    /**
     * 只更新类中的某个字段的时候
     * 只需要把要更新的那个字段设置为public volatile,利用反射来实现CAS操作
     */
    public static void atomicReferenceFieldUpdater(){
    //User类中的age字段需要进行原子操作,类型是String,字段名是age
        AtomicReferenceFieldUpdater arfu = AtomicReferenceFieldUpdater.newUpdater(User.class, String.class, "age");
        User u = new User("senninha","12");
        arfu.compareAndSet(u, u.age, "13");
        System.out.println(u.getAge());
    }
}

class User{
    public String username;
    public volatile String age;
    
    public User(String username, String age) {
        super();
        this.username = username;
        this.age = age;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("User [username=");
        builder.append(username);
        builder.append(", age=");
        builder.append(age);
        builder.append("]");
        return builder.toString();
    }
    
}
4.原子更新数组

传入后的会重新复制一份数组的拷贝,所以可以用原数组的值作为compare的比较对象.

    /**
     * 原子更新数组
     */
    public static void atomicArrayUpdater(){
        User[] user = new User[2];
        user[0] = new User("senninha", "1");
        user[1] = new User("senninha", "2");
        AtomicReferenceArray ara = new AtomicReferenceArray(user);
        //index,更新前的expect对象,如果expect传入新的对象
        ara.weakCompareAndSet(0, user[0], new User("senninha","3"));
        System.out.println(user[0]);
        System.out.println(ara.get(0));
    }

你可能感兴趣的:(atomic包下几个类的用法)