本文参考自Disruptor 源码解析
查看原文: 原文地址
本文的一些理解基于http://ifeve.com/?x=29&y=10&s=disruptor 一系列文章
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));
}//这样的设计应该就是解决伪共享,预读数组,求余操作优化