- 所有超级接口:
SequenceBarrier
- 所有已知实现类:
MpUnboundedBufferSequencer,MultiProducerSequencer,RingBufferSequencer,SingleProducerSequencer
2. 生产者与消费最慢的消费者之间进行协调 --
SequenceBarrier.dependentSequence()即为最慢的消费者进度,如果有消费者的话。3. 生产者之间可能毫无关系,因此生产者之间的协调需要由屏障实现。
4. 生产者由于明确知道自己要生产的数据数量,因此tryNext(n)的接口更易于使用。
Q: 生产者为什么没有等待策略?
A:一开始我确实尝试添加等待策略,后来发现没有意义。我在SequenceBlocker中提到,生产者不能使用Condition等待消费者,
因此等待策略的扩展性很有限,除了短暂的挂起线程外,没有好的替代方法。
Q: 生产者为什么没有ConsumerBarrier.alert()信号?
A:我们将生产者归属于外部系统,而将消费者归属于内部系统。生产者可能仅有部分逻辑与Sequencer相关,我们不能使用alert信号来中断或终止生产者。
- 作者:
- wjybxx date - 2024/1/16
-
字段概要
从接口继承的字段 cn.wjybxx.disruptor.SequenceBarrier
INITIAL_SEQUENCE -
方法概要
修饰符和类型方法说明获取用于阻塞等待序号的阻塞器。longgetHighestPublishedSequence(long nextSequence, long availableSequence) 查询 [nextSequence , availableSequence] 区间段之间连续发布的最大序号。booleanhasAvailableCapacity(int requiredCapacity) 是否有足够的空间 Has the buffer got capacity to allocate another sequence.booleanisPublished(long sequence) 指定序号的数据是否已发布。longnext()获取下一个事件的序号,空间不足时会阻塞(等待)。longnext(int n) 获取接下来的n个事件的序号,空间不足时会阻塞(等待)。long在next()基础上会响应中断请求longnextInterruptibly(int n) 在next(int)基础上会响应中断请求voidpublish(long sequence) 发布指定序号的数据,表示sequence对应的数据可用 Publishes a sequence.voidpublish(long lo, long hi) 批量发布数据,表示 [lowest,highest]区间段整段数据可用。void唤醒所有因条件等待阻塞的线程getBlocker()的快捷方法longtryNext()尝试获取下一个事件的序列 -- 不会阻塞。longtryNext(int n) 尝试获取接下来n个数据的最后一个数据索引位置 -- 不会阻塞。long在给定时间内尝试申请序号 注意:受限于等待策略的扩展限制,该接口本质是tryNext(int)的循环快捷方法。从接口继承的方法 cn.wjybxx.disruptor.SequenceBarrier
addDependentBarriers, claim, dependentSequence, groupSequence, minimumSequence, removeDependentBarrier, sequence
-
方法详细资料
-
hasAvailableCapacity
boolean hasAvailableCapacity(int requiredCapacity) 是否有足够的空间 Has the buffer got capacity to allocate another sequence. This is a concurrent method so the response should only be taken as an indication of available capacity.- 参数:
requiredCapacity- in the buffer- 返回:
- true if the buffer has the capacity to allocate the next sequence otherwise false.
-
next
long next()获取下一个事件的序号,空间不足时会阻塞(等待)。 申请完空间之后,必须使用publish(long)发布,否则会导致整个数据结构不可用。Claim the next event in sequence for publishing.
- 返回:
- the claimed sequence value
-
next
long next(int n) 获取接下来的n个事件的序号,空间不足时会阻塞(等待)。 申请完空间之后,必须使用publish(long, long)发布,否则会导致整个数据结构不可用Claim the next n events in sequence for publishing. This is for batch event producing. Using batch producing requires a little care and some math.
int n = 10; long hi = sequencer.next(n); long lo = hi - (n - 1); for (long sequence = lo; sequence <= hi; sequence++) { // Do work. } sequencer.publish(lo, hi);- 参数:
n- the number of sequences to claim- 返回:
- the highest claimed sequence value
-
tryNext
long tryNext()尝试获取下一个事件的序列 -- 不会阻塞。 申请完空间之后,必须使用publish(long)发布,否则会导致整个数据结构不可用。Attempt to claim the next event in sequence for publishing. Will return the number of the slot if there is at least
requiredCapacityslots available.- 返回:
- 申请成功则返回对应的序号,否则返回 -1
-
tryNext
long tryNext(int n) 尝试获取接下来n个数据的最后一个数据索引位置 -- 不会阻塞。 申请完空间之后,必须使用publish(long, long)发布,否则会导致整个数据结构不可用 使用该方法可以避免死锁Attempt to claim the next n events in sequence for publishing. Will return the highest numbered slot if there is at least
requiredCapacityslots available. Have a look atnext()for a description on how to use this method.- 参数:
n- 需要申请的序号数量- 返回:
- 申请成功则返回对应的序号,否则返回 -1
-
publish
void publish(long sequence) 发布指定序号的数据,表示sequence对应的数据可用 Publishes a sequence. Call when the event has been filled.- 参数:
sequence- the sequence to be published.
-
publish
void publish(long lo, long hi) 批量发布数据,表示 [lowest,highest]区间段整段数据可用。 一般情况下,hi是next()等方法申请到的最大序号,但也可能不是,生产者可能分段发布数据,以避免阻塞消费者。Batch publish sequences. Called when all of the events have been filled.
- 参数:
lo- first sequence number to publishhi- last sequence number to publish
-
isPublished
boolean isPublished(long sequence) 指定序号的数据是否已发布。 注意: 1. 该测试只测试序号自身,不测试其前置序号。 2. 通常情况下你不应该使用它,唯一合理的情况是:清理RingBuffer的时候。Confirms if a sequence is published and the event is available for use; non-blocking.
- 参数:
sequence- of the buffer to check- 返回:
- true if the sequence is available for use, false if not
-
getHighestPublishedSequence
long getHighestPublishedSequence(long nextSequence, long availableSequence) 查询 [nextSequence , availableSequence] 区间段之间连续发布的最大序号。 该接口用于消费者屏障查询真实可用的序号。由于多线程的生产者是先申请序号,再发布数据;因此
SequenceBarrier.sequence()指向的是即将发布数据的槽,而不一定已经具备数据。 而消费者只能顺序消费,因此【只要消费者的依赖可能包含生产者】,在观察到依赖的最大可用序号后,都应该查询真实可用的序号。Get the highest sequence number that can be safely read from the ring buffer. Depending on the implementation of the Sequencer this call may need to scan a number of values in the Sequencer. The scan will range from nextSequence to availableSequence. If there are no available values
>= nextSequencethe return value will benextSequence - 1. To work correctly a consumer should pass a value that is 1 higher than the last sequence that was successfully processed.- 参数:
nextSequence- The sequence to start scanning from.availableSequence- The sequence to scan to.- 返回:
- The highest value that can be safely read, will be at least
nextSequence - 1.
-
nextInterruptibly
在next()基础上会响应中断请求- 抛出:
InterruptedException- 如果申请期间线程被中断
-
nextInterruptibly
在next(int)基础上会响应中断请求- 抛出:
InterruptedException- 如果申请期间线程被中断
-
tryNext
在给定时间内尝试申请序号 注意:受限于等待策略的扩展限制,该接口本质是tryNext(int)的循环快捷方法。- 参数:
n- 需要申请的序号数量- 返回:
- 申请成功则返回对应的序号,否则返回 -1
-
getBlocker
获取用于阻塞等待序号的阻塞器。 注意:可能为null,如果整个系统禁用了基于锁的条件等待。 -
signalAllWhenBlocking
void signalAllWhenBlocking()唤醒所有因条件等待阻塞的线程getBlocker()的快捷方法
-