victory的博客

长安一片月,万户捣衣声

0%

并发 | Java中的12个原子操作类

Java中的13个原子操作类

在java.util.concurrent.atomic包中包含了12个原子类,属于四种类型的原子更新方式,分别是:
(1)原子更新基本类型
AtomicInteger:原子更新整型;
AtomicBoolean:原子更新布尔类型;
AtomicLong:源自更新长整型。
(2)原子更新数组
AtomicIntegerArray:原子更新整型数组里的元素;
AtomicLongArray:原子更新长整型数组里的元素;
AtomicReferenceArray:原子更新引用类型数组里的元素
(3)原子更新引用
AtomicReference:原子更新引用类型;
AtomicReferenceFieldUpdater:原子更新引用类型里的字段;
AtomicMarkableReference:原子更新带有标记位的引用类型(可以原子更新一个布尔类型的标记位和引用类型)。
(4)原子更新属性(字段)
AtomicIntegerFieldUpdater:原子更新整型的字段的更新器;
AtomicLongFieldUpdater:原子更新长整型的字段的更新器;
AtomicStampedReference:原子更新带有版本号的引用类型,能够解决使用CAS进行原子更新时可能出现的ABA问题。
以下给出每个类型的原子更新的一个示例代码:

示例代码1-原子更新基本类型

package concurrency.atomic;

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest1 {
    static AtomicInteger ai = new AtomicInteger(1);
    
    public static void main(String[] args){
        int addAndGet = ai.addAndGet(2);
        System.out.println(addAndGet);
    
        boolean compareAndSet = ai.compareAndSet(1, 2);
        System.out.println(compareAndSet);
        System.out.println(ai.get());
        
        System.out.println(ai.getAndIncrement());
        System.out.println(ai.get());
        
        ai.lazySet(3);
        System.out.println(ai.get());
        
        int andSet = ai.getAndSet(2);
        System.out.println(andSet);
        System.out.println(ai.get());
    }
}

示例代码2-原子更新数组

package concurrency.atomic;

import java.util.concurrent.atomic.AtomicIntegerArray;

public class AtomicIntegerArrayTest {
    static int[] value = new int[]{1,2};
    static AtomicIntegerArray ai = new AtomicIntegerArray(value);
    
    public static void main(String[] args){
        System.out.println(ai.getAndSet(0, 3));
        System.out.println(ai.get(0));
        System.out.println(value[0]);
        int addAndGet = ai.addAndGet(0, 3);
        System.out.println(addAndGet);
        System.out.println(ai.get(0));
        System.out.println(ai.compareAndSet(0, 3, 33));
        System.out.println(ai.compareAndSet(0, 6, 66));

    }
}

示例代码3-原子更新引用

package concurrency.atomic;

import java.util.concurrent.atomic.AtomicReference;


public class AtomicReferenceTest {
    public static AtomicReference<User> atomicUserRef = new AtomicReference<User>();
    
    public static void main(String[] args){
        User user = new User("conan", 15);
        atomicUserRef.set(user);
        User updateUser = new User("Shinichi", 17);
        atomicUserRef.compareAndSet(user, updateUser);
        System.out.println(atomicUserRef.get().getName());
        System.out.println(atomicUserRef.get().getOld());
    }
    
    static class User{
        private String name;
        private int old;
        
        public User(String name, int old){
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getOld() {
            return old;
        }

        public void setOld(int old) {
            this.old = old;
        }
    }
}

示例代码4-原子更新属性

package concurrency.atomic;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntegerFieldUpdaterTest {
    //创建原子更新器,并设置需要更新的对象和对象的属性
    private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class, "old");
    
    public static void main(String[] args){
        //设置柯南的年龄是10岁
        User conan = new User("conan", 10);
        //柯南长了一岁,但是仍然会输出旧的年龄
        System.out.println(a.getAndIncrement(conan));
        //输出柯南现在的年龄
        System.out.println(a.get(conan));
    }
    
    public static class User{
        private String name;
        public volatile int old;
        
        public User(String name, int old){
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public int getOld() {
            return old;
        }
    }
}