java.util.concurrent.atomic分类

转载自:https://juejin.im/post/5aeec351518825670a103292#heading-2

其余转载内容放在对应段落

java.util.concrrent.atomic包分类

原子更新基本类型AtomicBoolean以原子更新的方式更新boolean
AtomicInteger以原子更新的方式更新Integer
AtomicLong以原子更新的方式更新Long
原子更新数组类型AtomicIntegerArray原子更新整型数组中的元素
AtomicLongArray原子更新长整型数组中的元素
AtomicReferenceArray原子更新引用类型数组中的元素
原子更新引用类型AtomicReference原子更新引用类型
AtomicReferenceFieldUpdater原子更新引用类型里的字段
AtomicMarkableReference原子更新带有标记位的引用类型
原子更新字段类型AtomicIntegerFieldUpdater原子更新整型字段类
AtomicLongFiledUpdater原子更新长整型字段类
AtomicStampedReference原子更新引用类型,这种更新方式会带有版本号。而为什么在更新的时候会带有版本号,是为了解决CAS的ABA问题
jdk1.8扩展类DoubleAccumulator四个原理相似,LongAdder和对应的AtomicLong而言性能更高。AtomicLong在高并发场景下CAS可能会导致多个线程自旋,性能消耗太大;LongAdder采用锁分段的思想,在高并发场景下利用创建Cell数组(数组最大长度等于CPU核数),把竞态线程分发到不同的Cell数组分别做CAS处理,减少争用的自旋操作;在get最新值时需要把base值(对象基础值,都在此值上操作)和cell数组中所有的值相加返回;参考https://github.com/aCoder2013/blog/issues/22
DoubleAdder
LongAccumulator
LongAdder
Striped64

并发计数组件,是上面四个类型(LongAdder)的实现基础,采用Cell数组在高并发场景下将线程分摊到Cell数组中,锁分段减少竞态提高并发性能,相关参考https://www.jianshu.com/p/30d328e9353b

各种分类的用法

原子更新基本类型

实现机制参考https://blog.csdn.net/jiankangcs/article/details/94588590 这里不做说明

原子更新数组类型

以AtomicIntegerArray为例

/**
* 更新数组元素第i个值并返回更改前的最新值
*/
public final int getAndAdd(int i, int delta) {
    // checkedByteOffset(i)获取数组中第i个元素内存偏移位置
    return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
}

// 案例
public class AtomicDemo {
    //    private static AtomicInteger atomicInteger = new AtomicInteger(1);
    private static int[] value = new int[]{1, 2, 3};
    private static AtomicIntegerArray integerArray = new AtomicIntegerArray(value);

    public static void main(String[] args) {
        //对数组中索引为1的位置的元素加5
        int result = integerArray.getAndAdd(1, 5);
        System.out.println(integerArray.get(1));
        System.out.println(result);
    }
}
// 输出结果:
// 7
// 2

原子更新引用类型

public class AtomicReferenceTest {
    private static AtomicReference<User> reference = new AtomicReference<>();

    public static void main(String[] args) {
        User user1 = new User("a", 1);
        reference.set(user1);
        User user2 = new User("b",2);
        User user = reference.getAndSet(user2);
        System.out.println(user);
        System.out.println(reference.get());
        System.out.println(user1);
    }

    static class User {
        private String userName;
        private int age;

        public User(String userName, int age) {
            this.userName = userName;
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "userName='" + userName + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

}
// 输出结果:
// User{userName='a', age=1}
// User{userName='b', age=2}

// User{userName='a', age=1}

原子更新字段类型

要想使用原子更新字段需要两步操作:

  1. 原子更新字段类都是抽象类,只能通过静态方法newUpdater来创建一个更新器,并且需要设置想要更新的类和属性;
  2. 更新类的属性必须使用public volatile进行修饰;
public class AtomicFiledTest {
    private static AtomicIntegerFieldUpdater updater = AtomicIntegerFieldUpdater.newUpdater(User.class,"age");
    public static void main(String[] args) {
        User user = new User("a", 1);
        int oldValue = updater.getAndAdd(user, 5);
        System.out.println(oldValue);
        System.out.println(updater.get(user));
    }

    static class User {
        private String userName;
        public volatile int age;

        public User(String userName, int age) {
            this.userName = userName;
            this.age = age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "userName='" + userName + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

}
// 1
// 6

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值