RingBuffer是Disruptor最重要的核心组件,可以理解为一个环形队列,用来存储事件,生产者往队列上面存放事件,消费者去读取。内部是如何实现的,我们来看下源码。
1.类结构
/**
* Ring based store of reusable entries containing the data representing
* an event being exchanged between event producer and {@link EventProcessor}s.
*
* @param implementation storing the data for sharing during exchange or parallel coordination of an event.
*/
public final class RingBuffer extends RingBufferFields implements Cursored, EventSequencer, EventSink
1.1 Cursored
public interface Cursored
{
/**
* Get the current cursor value.
*
* @return current cursor value
*/
long getCursor();
}
Cursored接口只提供了一个获取当前序列值(游标)的方法
1.2 EventSequencer
public interface EventSequencer extends DataProvider, Sequenced
{
}
public interface DataProvider
{
T get(long sequence);
}
public interface EventSink
{
/**
* Publishes an event to the ring buffer. It handles
* claiming the next sequence, getting the current (uninitialised)
* event from the ring buffer and publishing the claimed sequence
* after translation.
*
* @param translator The user specified translation for the event
*/
void publishEvent(EventTranslator translator);
...
}
abstract class RingBufferPad
{
protected long p1, p2, p3, p4, p5, p6, p7;
}
abstract class RingBufferFields extends RingBufferPad
{
private static final int BUFFER_PAD;
private static final long REF_ARRAY_BASE;
private static final int REF_ELEMENT_SHIFT;
private static final Unsafe UNSAFE = Util.getUnsafe();
static
{
//获取object数组元素的大小
final int scale = UNSAFE.arrayIndexScale(Object[].class);
if (4 == scale)
{
REF_ELEMENT_SHIFT = 2;
}
else if (8 == scale)
{
REF_ELEMENT_SHIFT = 3;
}
else
{
throw new IllegalStateException("Unknown pointer size");
}
BUFFER_PAD = 128 / scale;
// Including the buffer pad in the array base offset 对象头的长度可以通过arrayBaseOffset获取
REF_ARRAY_BASE = UNSAFE.arrayBaseOffset(Object[].class) + (BUFFER_PAD << REF_ELEMENT_SHIFT);
}
private final long indexMask;
private final Object[] entries;
protected final int bufferSize;
protected final Sequencer sequencer;
RingBufferFields(
EventFactory 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)
{
throw new IllegalArgumentException("bufferSize must be a power of 2");
}
this.indexMask = bufferSize - 1;
//entries数组长度比实际设置的bufferSize大,数组两侧都要填充BUFFER_PAD个空数据组位
this.entries = new Object[sequencer.getBufferSize() + 2 * BUFFER_PAD];
fill(eventFactory);
}
// entries本身根据引用大小进行了填充,假设引用大小为4字节,BUFFER_PAD计算为32,数组两侧都要填充32个空数组位
private void fill(EventFactory eventFactory)
{
for (int i = 0; i < bufferSize; i++)
{
entries[BUFFER_PAD + i] = eventFactory.newInstance();
}
}
//根据填充的偏移量取值
@SuppressWarnings("unchecked")
protected final E elementAt(long sequence)
{
return (E) UNSAFE.getObject(entries, REF_ARRAY_BASE + ((sequence & indexMask) << REF_ELEMENT_SHIFT));
}
}
/**
* Ring based store of reusable entries containing the data representing
* an event being exchanged between event producer and {@link EventProcessor}s.
*
* @param implementation storing the data for sharing during exchange or parallel coordination of an event.
*/
public final class RingBuffer extends RingBufferFields implements Cursored, EventSequencer, EventSink
{
public static final long INITIAL_CURSOR_VALUE = Sequence.INITIAL_VALUE;
protected long p1, p2, p3, p4, p5, p6, p7;
/**
* Create a new Ring Buffer with the specified producer type (SINGLE or MULTI)
*
* @param Class of the event stored in the ring buffer.
* @param producerType producer type to use {@link ProducerType}.
* @param factory used to create events within the ring buffer.
* @param bufferSize number of elements to create within the ring buffer.
* @param waitStrategy used to determine how to wait for new elements to become available.
* @return a constructed ring buffer.
* @throws IllegalArgumentException if bufferSize is less than 1 or not a power of 2
*/
public static RingBuffer create(
ProducerType producerType,
EventFactory factory,
int bufferSize,
WaitStrategy waitStrategy)
{
switch (producerType)
{
case SINGLE:
return createSingleProducer(factory, bufferSize, waitStrategy);
case MULTI:
return createMultiProducer(factory, bufferSize, waitStrategy);
default:
throw new IllegalStateException(producerType.toString());
}
}
public static RingBuffer createSingleProducer(
EventFactory factory,
int bufferSize,
WaitStrategy waitStrategy)
{
SingleProducerSequencer sequencer = new SingleProducerSequencer(bufferSize, waitStrategy);
return new RingBuffer(factory, sequencer);
}
public static RingBuffer createMultiProducer(
EventFactory factory,
int bufferSize,
WaitStrategy waitStrategy)
{
MultiProducerSequencer sequencer = new MultiProducerSequencer(bufferSize, waitStrategy);
return new RingBuffer(factory, sequencer);
}
/**
* 获取指定序列号上面的事件槽,有两个使用的地方,事件生产者和事件消费者申请到序列之后,都会通过这个方法生产或者发布事件
**/
@Override
public E get(long sequence)
{
return elementAt(sequence);
}
/**
* 按照递增返回队列下一个序列号
**/
@Override
public long next()
{
return sequencer.next();
}
/**
* 指定n个之后队列下一个序列号
**/
@Override
public long next(int n)
{
return sequencer.next(n);
}
@Override
public long tryNext() throws InsufficientCapacityException
{
return sequencer.tryNext();
}
功能跟next类似,不同点在于next如果队列满了,会一直阻塞等待事件槽,而tryNext则会直接抛异常
public void addGatingSequences(Sequence... gatingSequences)
{
sequencer.addGatingSequences(gatingSequences);
}
public long getMinimumGatingSequence()
{
return sequencer.getMinimumSequence();
}
public boolean removeGatingSequence(Sequence sequence)
{
return sequencer.removeGatingSequence(sequence);
}
@Override
public void publishEvent(EventTranslator translator)
{
final long sequence = sequencer.next();
translateAndPublish(translator, sequence);
}
private void translateAndPublish(EventTranslator translator, long sequence)
{
try
{
translator.translateTo(get(sequence), sequence);
}
finally
{
sequencer.publish(sequence);
}
}