zoukankan      html  css  js  c++  java
  • 原子类型字段更新器AtomicXxxxFieldUpdater


    本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。

    并发编程系列博客传送门


    原子类型字段更新器

    java.util.concurrent.atomic中,原子类型字段更新器有以下三种:

    • AtomicIntegerFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定int类型字段。
    • AtomicLongFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定long类型字段。
    • AtomicReferenceFieldUpdater:基于反射的工具类,可以原子性的更新指定对象的指定应用类型字段。

    使用规则

    原子类型字段更新器在内部通过Unsafe类的native方法保证操作的原子性。

    关于原子类型字段更新器的使用需要注意以下几个方面:

    • 字段必须是volatile类型的,用于保证可见性。
    • 字段和字段更新器的访问类型(public/protected/private)必须一致。
    • 字段只能是实例变量,不能是类变量(static)。
    • 字段不能是final的变量,这样的字段不可修改。
    • 如果要处理Integer和Long类型,则需要使用AtomicReferenceFieldUpdater

    使用列子(以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;
            }
        }
    }
    

    方法说明

    首先学习上述三种原子类型字段更新器的通用方法,这些方法如下:

    • 构造器:只有一个无参protected的构造函数,并不可用。
    • newUpdater(fieldClass,fieldName):原子类型字段更新器提供的一个静态泛型方法,用于创建和返回指定字段和指定类型的原子类型字段更新器实例对象。
    • get(obj):赋值,具有原子性和可见性。
    • set(obj):取值,具有原子性和可见性。
    • lazySet(obj,newValue):赋值,具有原子性,不具备可见性。
    • getAndSet(obj,newValue):赋值并返回旧值,具有原子性和可见性。
    • compareAndSet(obj,expect,update):如果当前是期望值则赋值并返回赋值成功与否,具有原子性和可见性。
    • weakCompareAndSet(obj,expect,update):与compareAndSet(obj,expect,update)类似。

    原子类型字段更新器的通用方法与普通原子类型的通用方法类似,唯一的区别在于多了一个参数:obj(被修改的字段的所属对象)。

    AtomicIntegerFieldUpdater和AtomicLongFieldUpdater的独有方法,下面这些方法AtomicReferenceFieldUpdater类没有:

    • getAndAdd(obj):增量计算并返回旧值,具有原子性和可见性。
    • addAndGet(obj):增量计算并返回新值,具有原子性和可见性。
    • getAndIncrement(obj):自增并返回旧值,类似i ++,具有原子性和可见性。
    • incrementAndGet(obj):自增并返回新值,类似++ i,具有原子性和可见性。
    • getAndDecrement(obj):自减并返回旧值,类似i --,具有原子性和可见性。
    • decrementAndGet(obj):自减并返回新值,类似-- i,具有原子性和可见性。
  • 相关阅读:
    Codeforces 1166 D. Cute Sequences 构造
    ZOJ 4103 浙江省第16届大学生程序设计竞赛 D题 Traveler 构造
    ZOJ 4100 浙江省第16届大学生程序设计竞赛 A题 Vertices in the Pocket 线段树+并查集
    若干结论和定理(持续更新)
    三类经典贪心问题
    2018 ICPC Asia Xuzhou Regional M. Rikka with Illuminations
    Educational Codeforces Round 99
    2018 CCPC-Final K
    2020浙江省赛 Huge Clouds
    BZOJ1030 文本生成器(AC自动机+DP)
  • 原文地址:https://www.cnblogs.com/54chensongxia/p/12167772.html
Copyright © 2011-2022 走看看