Package com.lmax.disruptor

The Disruptor is a concurrent programming framework for exchanging and coordinating work on a continuous series of items.

See:
          Description

Interface Summary
BatchHandler<T extends AbstractEntry> Callback interface to be implemented for processing AbstractEntrys as they become available in the RingBuffer
ClaimStrategy Strategies employed for claiming the sequence of AbstractEntrys in the RingBuffer by producers.
Consumer EntryConsumers waitFor AbstractEntrys to become available for consumption from the RingBuffer
ConsumerBarrier<T extends AbstractEntry> Coordination barrier for tracking the cursor for producers and sequence of dependent Consumers for a RingBuffer
EntryFactory<T extends AbstractEntry> Called by the RingBuffer to pre-populate all the AbstractEntrys to fill the RingBuffer.
EntryTranslator<T extends AbstractEntry> Implementations translate a other data representations into AbstractEntrys claimed from the RingBuffer
ExceptionHandler Callback handler for uncaught exceptions in the AbstractEntry processing cycle of the BatchConsumer
ForceFillProducerBarrier<T extends AbstractEntry> Abstraction for claiming AbstractEntrys in a RingBuffer while tracking dependent Consumers.
LifecycleAware Implement this interface to be notified when a thread for the BatchConsumer starts and shuts down.
ProducerBarrier<T extends AbstractEntry> Abstraction for claiming AbstractEntrys in a RingBuffer while tracking dependent Consumers
SequenceTrackingHandler<T extends AbstractEntry> Used by the BatchConsumer to set a callback allowing the BatchHandler to notify when it has finished consuming an AbstractEntry if this happens after the BatchHandler.onAvailable(AbstractEntry) call.
WaitStrategy Strategy employed for making Consumers wait on a RingBuffer.
 

Class Summary
AbstractEntry Base implementation that must be extended for RingBuffer entries.
BatchConsumer<T extends AbstractEntry> Convenience class for handling the batching semantics of consuming entries from a RingBuffer and delegating the available AbstractEntrys to a BatchHandler.
ClaimStrategy.MultiThreadedStrategy Strategy to be used when there are multiple producer threads claiming AbstractEntrys.
ClaimStrategy.SingleThreadedStrategy Optimised strategy can be used when there is a single producer thread claiming AbstractEntrys.
FatalExceptionHandler Convenience implementation of an exception handler that using standard JDK logging to log the exception as Level.SEVERE and re-throw it wrapped in a RuntimeException
IgnoreExceptionHandler Convenience implementation of an exception handler that using standard JDK logging to log the exception as Level.INFO
NoOpConsumer No operation version of a Consumer that simply tracks a RingBuffer.
RingBuffer<T extends AbstractEntry> Ring based store of reusable entries containing the data representing an AbstractEntry being exchanged between producers and consumers.
SequenceBatch Used to record the batch of sequences claimed in a RingBuffer.
Util Set of common functions used by the Disruptor
WaitStrategy.BlockingStrategy Blocking strategy that uses a lock and condition variable for Consumers waiting on a barrier.
WaitStrategy.BusySpinStrategy Busy Spin strategy that uses a busy spin loop for Consumers waiting on a barrier.
WaitStrategy.YieldingStrategy Yielding strategy that uses a Thread.yield() for Consumers waiting on a barrier.
 

Enum Summary
ClaimStrategy.Option Indicates the threading policy to be applied for claiming AbstractEntrys by producers to the RingBuffer
WaitStrategy.Option Strategy options which are available to those waiting on a RingBuffer
 

Exception Summary
AlertException Used to alert consumers waiting at a ConsumerBarrier of status changes.
 

Package com.lmax.disruptor Description

The Disruptor is a concurrent programming framework for exchanging and coordinating work on a continuous series of items. It can be used as an alternative to wiring processing stages together via queues. The Disruptor design has the characteristics of generating significantly less garbage than queues and separates the concurrency concerns so non-locking algorithms can be employed resulting in greater scalability and performance.

It works on the principle of having a number of stages that are each single threaded with local state and memory. No global memory exists and all communication is achieved by passing messages/state via managed ring buffers.

Almost any graph or pipeline structure can be composed via one or more Disruptor patterns.

UniCast a series of items between 1 producer and 1 consumer.

                                               track to prevent wrap
                                         +-----------------------------+
                                         |                             |
                                         |                             v
+----+    +----+             +----+    +====+    +====+    +====+    +----+
| P0 |--->| C0 |             | P0 |--->| PB |--->| RB |<---| CB |    | C0 |
+----+    +----+             +----+    +====+    +====+    +====+    +----+
                                            claim      get    ^        |
                                                              |        |
                                                              +--------+
                                                                waitFor
        

Sequence a series of messages from multiple producers

                                               track to prevent wrap
                                         +-----------------------------+
                                         |                             |
                                         |                             v
+----+                       +----+    +====+    +====+    +====+    +----+
| P0 |------+                | P0 |--->| PB |--->| RB |<---| CB |    | C0 |
+----+      |                +----+    +====+    +====+    +====+    +----+
            v                            ^  claim      get    ^        |
+----+    +----+             +----+      |                    |        |
| P1 |--->| C1 |             | P1 |------+                    +--------+
+----+    +----+             +----+      |                      waitFor
            ^                            |
+----+      |                +----+      |
| P2 |------+                | P2 |------+
+----+                       +----+
        

Pipeline a series of messages

                          +----+    +----+    +----+    +----+
                          | P0 |--->| C0 |--->| C1 |--->| C2 |
                          +----+    +----+    +----+    +----+



                  track to prevent wrap
            +------------------------------------------------------------------------+
            |                                                                        |
            |                                                                        v
+----+    +====+    +====+    +=====+    +----+    +=====+    +----+    +=====+    +----+
| P0 |--->| PB |--->| RB |    | CB0 |<---| C0 |<---| CB1 |<---| C1 |<---| CB2 |<---| C2 |
+----+    +====+    +====+    +=====+    +----+    +=====+    +----+    +=====+    +----+
               claim   ^  get    |   waitFor          |  waitFor           |  waitFor
                       |         |                    |                    |
                       +---------+--------------------+--------------------+
        

Multicast a series of messages to multiple consumers

          +----+                                        track to prevent wrap
   +----->| C0 |                         +-----------------------------+---------+---------+
   |      +----+                         |                             |         |         |
   |                                     |                             v         v         v
+----+    +----+             +----+    +====+    +====+    +====+    +----+    +----+    +----+
| P0 |--->| C1 |             | P0 |--->| PB |--->| RB |<---| CB |    | C0 |    | C1 |    | C2 |
+----+    +----+             +----+    +====+    +====+    +====+    +----+    +----+    +----+
   |                                        claim      get    ^        |         |         |
   |      +----+                                              |        |         |         |
   +----->| C2 |                                              +--------+---------+---------+
          +----+                                                           waitFor
        

Replicate a message then fold back the results

          +----+                                  track to prevent wrap
   +----->| C0 |-----+                   +--------------------------------------+
   |      +----+     |                   |                                      |
   |                 v                   |                                      v
+----+             +----+    +----+    +====+    +====+            +=====+    +----+
| P0 |             | C2 |    | P0 |--->| PB |--->| RB |<-----------| CB1 |<---| C2 |
+----+             +----+    +----+    +====+    +====+            +=====+    +----+
   |                 ^                      claim   ^  get            |   waitFor
   |      +----+     |                              |                 |
   +----->| C1 |-----+                           +=====+    +----+    |
          +----+                                 | CB0 |<---| C0 |<---+
                                                 +=====+    +----+    |
                                                    ^                 |
                                                    |       +----+    |
                                                    +-------| C1 |<---+
                                                  waitFor   +----+
        

Code Example

    // Entry holder for data to be exchange that must extend AbstractEntry
    public final class ValueEntry extends AbstractEntry
    {
        private long value;

        public long getValue()
        {
            return value;
        }

        public void setValue(final long value)
        {
            this.value = value;
        }

        public final static EntryFactory<ValueEntry> ENTRY_FACTORY = new EntryFactory<ValueEntry>()
        {
            public ValueEntry create()
            {
                return new ValueEntry();
            }
        };
    }

    // Callback handler which can be implemented by consumers
    final BatchHandler<ValueEntry> batchHandler = new BatchHandler<ValueEntry>()
    {
        public void onAvailable(final ValueEntry entry) throws Exception
        {
            // process a new entry as it becomes available.
        }

        public void onEndOfBatch() throws Exception
        {
            // useful for flushing results to an IO device if necessary.
        }

        public void onCompletion()
        {
            // do any clean up before shutdown.
        }
    };

    RingBuffer<ValueEntry> ringBuffer =
        new RingBuffer<ValueEntry>(ValueEntry.ENTRY_FACTORY, SIZE,
                                   ClaimStrategy.Option.SINGLE_THREADED,
                                   WaitStrategy.Option.YIELDING);

    ConsumerBarrier<ValueEntry> consumerBarrier = ringBuffer.createConsumerBarrier();
    BatchConsumer<ValueEntry> batchConsumer = new BatchConsumer<ValueEntry>(consumerBarrier, batchHandler);
    ProducerBarrier<ValueEntry> producerBarrier = ringBuffer.createProducerBarrier(batchConsumer);

    // Each consumer runs on a separate thread
    EXECUTOR.submit(batchConsumer);

    // Producers claim entries in sequence
    ValueEntry entry = producerBarrier.nextEntry();

    entry.setValue(1234);

    // make the entry available to consumers
    producerBarrier.commit(entry);
    



Copyright © 2011 LMAX Ltd. All Rights Reserved.