Java中的原子类

在java.util.concurrent.atomic包中提供了一些原子操作类,使用它们可以完成对基本类型、数组类型、引用类型和字段值的原子更新,我们可以在不同的场景使用不同的原子类,如下:

  • AtomicInteger
  • AtomicBoolean
  • AtomicLong
  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReferenceArray
  • AtomicIntegerFieldUpdater
  • AtomicLongFieldUpdater
  • AtomicReferenceFieldUpdater
  • AtomicReference
  • AtomicStampedReference
  • AtomicMarkableReference

1 原子更新基本类型

在上面列出的原子类中,AtomicInteger、AtomicBoolean、AtomicLong三个类可以实现对基本类型的原子操作,接下来依次介绍这三个类的实现原理

1.1 AtomicInteger类的实现原理

该类常用的方法及源码如下(JDK1.8):

  • int getAndSet(int newValue): 设置值为指定的值,返回旧值

    public final int getAndSet(int newValue) {
         return unsafe.getAndSetInt(this, valueOffset, newValue);
     }
    
  • boolean compareAndSet(int expect, int update): 判断当前值是否为expect,是的话更新为update

     public final boolean compareAndSet(int expect, int update) {
     	   return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    
  • int getAndIncrement(): 将值加1,返回旧值

    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
    
  • int getAndDecrement(): 将值减1,返回旧值

    public final int getAndDecrement() {
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }
    
  • int getAndAdd(int delta): 将旧值和指定的值相加,返回旧值

    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }
    
  • int incrementAndGet(): 将值加1,返回新值

    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
    
  • int decrementAndGet(): 将值减1,返回新值

    public final int decrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
    }
    
  • int addAndGet(int delta): 将值和指定值相加,返回新值

    public final int addAndGet(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
    }
    
  • void lazySet(int newValue):

    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }
    

通过上述方法的源码可以看出AtomicInteger的原子操作是通过Unsafe类来实现的,查看Unsafe类中源码,可以发现是通过当中的compareAndSwapeInt方法实现的,Unsafe中提供的CAS(比较并替换)方法如下:

	public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);

    public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);

    public final native boolean compareAndSwapLong(Object o, long offset, long expected, long x);

上述方法的含义是当expected的值同当前内存中的值相同时,将其设置为x,否则返回失败。参数说明如下:

  • o:当前对象
  • offset:在内存中的偏移量
  • expected:期望值
  • x:需要修改成的值

在Unsafe.getAndAddInt方法中,在调用compareAndSwapInt方法外部是个循环,当调用compareAndSwapInt更新值成功后跳出循坏。

1.2 AtomicBoolean的实现原理

AtomicBoolean的实现原理同AtomicBoolean的实现原理一样,就不在贴其源码了,在AtomicBoolean的构造函数中会将boolean值使用int值来替换,然后使用Unsafe.compareAndSwapInt方法实现,1代表true 2代表false,如下:

    public AtomicBoolean(boolean initialValue) {
        value = initialValue ? 1 : 0;
    }

1.3 AtomicLong的实现原理

这里不再赘述,其实现原理同AtomicInteger一致,不同点是AtomicLong使用的Unsafe.compareAndSwapLong方法。

2 原子更新数组

  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReferenceArray
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值