美文网首页
原子操作类-数组(volatile+CAS循环;baseOffs

原子操作类-数组(volatile+CAS循环;baseOffs

作者: 王侦 | 来源:发表于2019-07-17 07:05 被阅读0次

以AtomicIntegerArray为例。

1.构造器和域

    private static final int base = unsafe.arrayBaseOffset(int[].class);
    private static final int shift;
    private final int[] array;
public AtomicIntegerArray(int length) {
        array = new int[length];
    }
    public AtomicIntegerArray(int[] array) {
        // Visibility guaranteed by final field guarantees
        this.array = array.clone();
    }

2.方法

2.1 采用baseOffset + i*indexScale获取数组第i个元素

    public final int get(int i) {
        return getRaw(checkedByteOffset(i));
    }

    private int getRaw(long offset) {
        return unsafe.getIntVolatile(array, offset);
    }
    static {
        int scale = unsafe.arrayIndexScale(int[].class);
        if ((scale & (scale - 1)) != 0)
            throw new Error("data type scale not a power of two");
        shift = 31 - Integer.numberOfLeadingZeros(scale);
    }

    private long checkedByteOffset(int i) {
        if (i < 0 || i >= array.length)
            throw new IndexOutOfBoundsException("index " + i);

        return byteOffset(i);
    }

    private static long byteOffset(int i) {
        return ((long) i << shift) + base;
    }

arrayBaseOffset,获取数组第一个元素的偏移地址。arrayIndexScale,数组中元素的大小,占用多少个字节。arrayBaseOffset与arrayIndexScale配合起来使用,就可以定位数组中每个元素在内存中的位置。

floor(log2(x)) = 31 - numberOfLeadingZeros(x)

如果这是一个int型数组,indexScale 等于4,那么 shift 值为2,所以乘以4和向左移2位,结果是一样的。

    public final int getAndSet(int i, int newValue) {
        return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);
    }

采用的也是CAS循环,转换为偏移量后,与AtomicInteger没有区别。

3.使用函数接口

    public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {
        long offset = checkedByteOffset(i);
        int prev, next;
        do {
            prev = getRaw(offset);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSetRaw(offset, prev, next));
        return prev;
    }
    public final int getAndAccumulate(int i, int x,
                                      IntBinaryOperator accumulatorFunction) {
        long offset = checkedByteOffset(i);
        int prev, next;
        do {
            prev = getRaw(offset);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSetRaw(offset, prev, next));
        return prev;
    }

相关文章

  • 原子操作类-数组(volatile+CAS循环;baseOffs

    以AtomicIntegerArray为例。 1.构造器和域 2.方法 2.1 采用baseOffset + i*...

  • ruby - 学习笔记

    字符操作 数组循环 异常 类 模块 字符操作 数组循环 异常 % 取余 << 字符接入,如 a<

  • 并发编程艺术-7

    本文主要介绍了java 中的 原子操作类,分为原子更新基本类型,原子更新数组,原子更新引用,原子更新属性,基本上都...

  • 高并发(12)-原子操作类的使用

    @TOC 前言 上篇文章讲解了什么是原子操作,并且怎么实现原子操作。今天就讲一下原子的操作类 什么是原子操作类 为...

  • java如何实现原子操作CAS

    在Java中可以通过锁和循环CAS的方式来实现原子操作。 使用循环CAS实现原子操作 JVM中的CAS操作正是利用...

  • java.util.concurrent.atomic源码学习(

    1.常用类概览 先看一下atomic主要包含哪些常用类 2.原子类&原子数组 在介绍原子类&原子数组前,首先要引入...

  • Java并发 之 Atomic 原子操作类

    Atomic 原子操作类 在java.util.concurrent.atomic包里提供了一组原子操作类,这些类...

  • 原子操作类

    原子操作类简介 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行...

  • Java - 原子操作类

    Java中的12个原子操作类 原子更新基本类型类 AtomicBoolean:原子更新布尔类型 AtomicInt...

  • Java原子类

    1、原子类的分类 原子操作是指一个不可中断的操作。 原子类是指具有原子操作特征的类。 JUC并发包中的原子类都存放...

网友评论

      本文标题:原子操作类-数组(volatile+CAS循环;baseOffs

      本文链接:https://www.haomeiwen.com/subject/tsrflctx.html