Disruptor with multiple consumers so that each event is only consumed once?

There are 2 approaches, the first is to use the WorkerPool. The second it to use the ‘striped’ EventHandler approach described below.

If we have 4 handlers and assign each an ordinal (0 through 3), then the consumer need only do a modulo operation using the sequence number and the number of consumers and compare it to its ordinal value.

public final class MyHandler implements EventHandler<ValueEvent>
{
    private final long ordinal;
    private final long numberOfConsumers;

    public MyHandler(final long ordinal, final long numberOfConsumers)
    {
        this.ordinal = ordinal;
        this.numberOfConsumers = numberOfConsumers;
    }

    public void onEvent(final ValueEvent entry, final long sequence, final boolean onEndOfBatch)
    {
        if ((sequence % numberOfConsumers) == ordinal)
        {
            // Process the event
        }
    }
}

Some would ask if one consumer takes too long on a transaction it will block all queued on that ordinal. Technically this is possible but one must consider that the batching effect then kicks in thus saving cost for those behind. With this approach the concurrency costs are so low you may find even small stalls are less costly than a queue based alternative.

DisruptorFrequently-Asked-Questions
并发框架Disruptor译文