Disruptor 缓冲行填充的进一步解释
2018-11-20 本文已影响262人
黄大海
最近学习Disruptor的使用。也看了不少介绍缓冲行的原理,比如这篇。其中关于缓冲行的实现,一直不太明白。为什么是15个long?不是更多或更少? 对于明白的同学可能很简单。对于我来说可能少了一些中间的说明。这两天突然开窍了,所以把它记录下来。先看代码:com.lmax.disruptor.Sequence
class LhsPadding
{
protected long p1, p2, p3, p4, p5, p6, p7;
}
class Value extends LhsPadding
{
protected volatile long value;
}
class RhsPadding extends Value
{
protected long p9, p10, p11, p12, p13, p14, p15;
}
public class Sequence extends RhsPadding
{
...
}
- java的lang类型占用8个字节。目前主流的缓冲行大小一般是64字节,也就是可以存放8个long。
- 缓冲行填充被设计成前面7个long, 后面7个long是为了保证有效数据和padding被任意分割的情况下都可以实现和其他无关数据不共享,从而避免相互影响(伪共享:因为无关数据变更而导致有效数据被清理出缓存,或者相反),见下图
- V=Value=有效值
- P=Padding=填充
- U=Unstable=不稳定无关数据
- 当然有效值不一定是long,也不一定是一个,可以推广到多个连续数据,例如com.lmax.disruptor.RingBuffer 中就有多个连续有效值
abstract class RingBufferPad
{
protected long p1, p2, p3, p4, p5, p6, p7;
}
abstract class RingBufferFields<E> extends RingBufferPad
{
private final long indexMask;
private final Object[] entries;
protected final int bufferSize;
protected final Sequencer sequencer;
...
}
public final class RingBuffer<E> extends RingBufferFields<E>{
protected long p1, p2, p3, p4, p5, p6, p7;
...
}