Disruptor 源码解析

本文的一些理解基于http://ifeve.com/?x=29&y=10&s=disruptor 一系列文章

disruptor 版本 3.4.2

RingBuffer  维护并发数据的缓冲数组


RingBuffer

因为一些相关参数都用到了,把这几个步骤一起说明,利于理解

静态模块初始化 + RingBufferFields构造函数

    private static final int BUFFER_PAD;//缓冲器填充padding
    private static final long REF_ARRAY_BASE;//数组对象头信息 + BUFFER_PAD * 引用指针大小  字节
    private static final int REF_ELEMENT_SHIFT;//引用指定大小  字节
    private static final Unsafe UNSAFE = Util.getUnsafe();

    static
    {
        final int scale = UNSAFE.arrayIndexScale(Object[].class);
        if (4 == scale)//开启指针压缩,引用大小为4字节
        {
            REF_ELEMENT_SHIFT = 2;
        }
        else if (8 == scale)//64位 未开启指针压缩,引用大小为8字节
        {
            REF_ELEMENT_SHIFT = 3;
        }
        else
        {
            throw new IllegalStateException("Unknown pointer size");
        }
        BUFFER_PAD = 128 / scale;//默认除了数组头信息外 再填充128个字节
        // Including the buffer pad in the array base offset
        REF_ARRAY_BASE = UNSAFE.arrayBaseOffset(Object[].class) + (BUFFER_PAD << REF_ELEMENT_SHIFT);
    }

    private final long indexMask;//bufferSize-1  非数组length - 1!!!
    private final Object[] entries;
    protected final int bufferSize;
    protected final Sequencer sequencer;

    RingBufferFields(
        EventFactory<E> eventFactory,
        Sequencer sequencer)
    {
        this.sequencer = sequencer;
        this.bufferSize = sequencer.getBufferSize();

        if (bufferSize < 1)
        {
            throw new IllegalArgumentException("bufferSize must not be less than 1");
        }
        if (Integer.bitCount(bufferSize) != 1)//ringbuffer的大小为2的幂次方
        {
            throw new IllegalArgumentException("bufferSize must be a power of 2");
        }

        this.indexMask = bufferSize - 1;
        this.entries = new Object[sequencer.getBufferSize() + 2 * BUFFER_PAD];//数组实际元素个数所占字节 + 128 * 2 字节  即开启指针压缩情况下,多64个元素,未开启指针压缩情况下,多32个元素
        fill(eventFactory);
    }

    private void fill(EventFactory<E> eventFactory)
    {
        for (int i = 0; i < bufferSize; i++)
        {
            entries[BUFFER_PAD + i] = eventFactory.newInstance();//数组从第33个元素或者第17个元素开始填充
        }
    }

看到fille函数的初始化就应该会发现 获取元素的方式肯定也有一些文章

    protected final E elementAt(long sequence)
    {//REF_ARRAY_BASE 数组初始化多填充了2 * BUFFER_PAD,前一个BUFFER_PAD所占字节就是在REF_ARRAY_BASE里
        return (E) UNSAFE.getObject(entries, REF_ARRAY_BASE + ((sequence & indexMask) << REF_ELEMENT_SHIFT));
    }//这样的设计应该就是解决伪共享,预读数组,求余操作优化



猜你喜欢

转载自blog.csdn.net/u012210451/article/details/81047861