【Java】原子类常用方法

1、compareAndSet


示例:

AtomicInteger atoimicInteger = new AtomicInteger(0);
aotimicInteger.compareAndSet(0, 1);
System.out.println(atoimicInteger.get())
---------
结果: 1

1)atoimicInteger 初始值为 0;

2)compareAndSet (expect, update),只有当 aotimicInteger 的值与期待值 expoect 相同时,才会执行更新操作,否则,不更新;

AtomicInteger atoimicInteger = new AtomicInteger(0);
aotimicInteger.compareAndSet(1, 2);
System.out.println(atoimicInteger.get())
---------
结果: 1

上述语句并不会将 atoimicInteger 更新为 2;

2、AtomicReferenceFieldUpdater


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

// 源码出处:https://www.jianshu.com/p/18dfc5fa0171
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,具体使用方法可参考:Atomic包之FieldUpdater深度解析 · Issue #10 · aCoder2013/blog · GitHub

参考文章:

Java原子属性更新器AtomicReferenceFieldUpdater的用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值