zoukankan      html  css  js  c++  java
  • Java原子属性更新器AtomicReferenceFieldUpdater的使用

    AtomicReferenceFieldUpdater是基于反射的工具类,用来将指定类型的指定的volatile引用字段进行原子更新,对应的原子引用字段不能是private的。通常一个类volatile成员属性获取值、设定为某个值两个操作时非原子的,若想将其变为原子的,则可通过AtomicReferenceFieldUpdater来实现。如下面例子:

    public class AtomicReferTest {
        public static void main(String[] args) throws Exception  
        {  
            AtomicReferenceFieldUpdater updater=AtomicReferenceFieldUpdater.newUpdater(Dog.class,String.class,"name");  
            Dog dog1=new Dog();  
            System.out.println(updater.compareAndSet(dog1,"dog1","compareAndSet"));        
            System.out.println(dog1.name);  
            System.out.println(updater.getAndSet(dog1, "getAndSet"));
            System.out.println(dog1.name);
        }  
    }
    class Dog  
    {  
         volatile  String name="dog1";  
      
    }  

    输出结果:

    true
    compareAndSet
    compareAndSet
    getAndSet

    通过调用AtomicReferenceFieldUpdater.newUpdater(Dog.class,String.class,"name")静态方法生成Dog类的String类型的name字段的原子修改器updater,然后调用它的compareAndSet方法判断dog1对象的name值是否为dog1,若是则返回true并修改其值。也可调用getAndSet方法直接修改dog1属性的name字段值,并返回该字段原来的值。

    Java类库中BufferedInputStream就调用了这个类:

    public
    class BufferedInputStream extends FilterInputStream {
    
        protected volatile byte buf[];
    
        /*
        *  原子的更新内部数组,比如扩容、关闭时,
        */
        private static final
            AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
            AtomicReferenceFieldUpdater.newUpdater
            (BufferedInputStream.class,  byte[].class, "buf");
    
    
        public void close() throws IOException {
            byte[] buffer;
            while ( (buffer = buf) != null) {
                //放在一个循环中,如果CAS更新失败,那么就读取最新的buf引用,继续CAS更新
                if (bufUpdater.compareAndSet(this, buffer, null)) {
                    InputStream input = in;
                    in = null;
                    if (input != null)
                        input.close();
                    return;
                }
            }
        }
    }

    AtomicReferenceFieldUpdater是Doug Lea在Java 5中写的atomic classes 中Filed Updater的一部分,本质上是volatile字段的包装器。相似的还有AtomicIntegerFieldUpdater,具体使用方法可参考:https://github.com/aCoder2013/blog/issues/10

    注意原子更新器的使用存在比较苛刻的条件如下

    • 操作的字段不能是static类型。

    • 操作的字段不能是final类型的,因为final根本没法修改。

    • 字段必须是volatile修饰的,也就是数据本身是读一致的。

    • 属性必须对当前的Updater所在的区域是可见的,如果不是当前类内部进行原子更新器操作不能使用private,protected子类操作父类时修饰符必须是protect权限及以上,如果在同一个package下则必须是default权限及以上,也就是说无论何时都应该保证操作类与被操作类间的可见性。

    Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

  • 相关阅读:
    sass环境搭建之node-sass,ruby
    对于模块加载:ES6、CommonJS、AMD、CMD的区别
    sass变量的作用域
    sass中的占位符%,@extend,@mixin(@include)的编译区别和使用场景
    遇到的问题
    全局配置
    组件或者dom的特殊属性
    全局API
    CentO7安装zookeeper并设置开机自启动
    MyBatis中TypeHandler的使用
  • 原文地址:https://www.cnblogs.com/doit8791/p/9098116.html
Copyright © 2011-2022 走看看