线程安全之原子性

原子操作

package ThreadDemo;

public class Thread9{

    volatile int i=0;

    public void count(){
        i++;
    }
}
  public void count();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: dup
         2: getfield      #2                  // Field i:I
         5: iconst_1
         6: iadd
         7: putfield      #2                  // Field i:I
        10: return

原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只是执行其中一部分(不可中断性)
将整个操作作为一个整体,资源在该次操作中保持一致,这是原子性的核心特征。

CAS(Compare and swap)
Compare and swap比较和交换。属于硬件同步原语,处理器提供了基本内存操作的原子性保证。
CAS操作需要输入两个数值,一个是旧值A和一个新值B,在操作期间对旧值进行比较,若没有变化,才换成新值,发生变化则不交换。
JAVAsun.misc.Unsafe类,提供了compareAndSwapInt()和compareAndSwapLong()等几个方法实现了CAS
在这里插入图片描述
通过Unsafe来自己实现AtomicInteger

public class CounterUnsafe {
    volatile int i = 0;

    private static Unsafe unsafe;

    private static long valueOffset;   //i字段的偏移量,从逻辑上代表了i字段

    static {
        //unsafe = Unsafe.getUnsafe();
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);

            Field iField = CounterUnsafe.class.getDeclaredField("i");
            valueOffset = unsafe.objectFieldOffset(iField);   //
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        AtomicInteger ii = new AtomicInteger();
        ii.incrementAndGet();
    }

    public void add() {
        for (;;){
            int current = unsafe.getIntVolatile(this, valueOffset);    //获取当前值
            //用CAS将值+1
            if (unsafe.compareAndSwapInt(this, valueOffset, current, current+1))
                break;
        }
    }
}

J.U.C包内的原子操作封装类
AtomicBoolean:原子更新布尔类型
AtomicInteger:原子更新整型
AtomicLong:原子更新长整型
AtomicIntegerArray:原子更新整型数组里的元素
AtomicLongArray:原子更新长整型数组里的元素
AtomicReferenceArray:原子更新引用类型数组中的元素
AtomicIntegerFieldUpdater:原子更新整型的字段的更新器
AtomicLongFieldUpdater:原子更新长整型字段的更新器
AtomicReferenceFieldUpdater:原子更新引用类型里的更强器
AtomicReference:原子更新的引用类型
AtomicStampedReference:原子更新带有版本号的引用类型
AtomicMarkableReference:原子带有标位的引用类型
1.8更新:
计数器增强版,高并发下性能更好
更新器:DoubleAccumulator、LongAccumulator
计数器:DoubleAdder、LongAdder
原理:分成多个操作单元,不同线程更新不同的单元只需要汇总的时候才计算所有单元的操作
场景:高并发频繁更新、不太频繁地读取

CAS的三个问题:
1.循环+CAS,自旋的实现让所有线程都处于高频运行,争抢CPU执行时间的状态。如果操作长时间不成功,会带来很大的CPU资源消耗。
2.针对单个变量的操作,不能用于多个变量来实现原子操作。
3.ABA问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值