Why Disruptor Beats Traditional Queues: A Deep Dive into High‑Performance Producer/Consumer Models
This article explains how the Disruptor framework achieves ultra‑low latency and high throughput in Java by using a ring‑buffer based producer/consumer model, detailing its architecture, sequencing algorithm, wait strategies, and practical code examples for both publishing and processing events.
Overview
The "multicore crisis" has revived interest in concurrent programming, but coordinating multiple threads introduces significant complexity, both in execution order dependencies and data consistency. Traditional Java concurrency utilities (wait/notify, locks, semaphores, etc.) solve isolated problems, yet they cannot efficiently handle the massive parallelism of modern multicore CPUs.
A clear architectural design is essential for concurrent projects; without it, thread coordination becomes unpredictable, bugs proliferate, and maintenance becomes painful.
Common Concurrency Models
Parallel model (used by JDK 8 streams)
Pipeline model (e.g., Netty)
Producer/Consumer model
Actor model (e.g., Akka)
These models encapsulate proven solutions from experienced engineers and simplify communication among team members.
Disruptor Producer Model
Disruptor implements a high‑performance producer/consumer pattern using a ring buffer. The producer workflow is:
Call Sequencer.next() to claim the next available slot in the ring buffer.
Check that the claimed slot is not still occupied by an unconsumed event (preventing overwriting).
Write the event data into the claimed slot.
Publish the sequence with Sequencer.publish(), which updates the cursor and wakes waiting consumers.
The next() method contains a loop that:
public long next(int n) throws IllegalArgumentException {
if (n < 1) throw new IllegalArgumentException("n must be > 0");
long nextValue = this.nextValue;
long nextSequence = nextValue + n;
long wrapPoint = nextSequence - bufferSize;
long cachedGatingSequence = this.cachedValue;
if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) {
// wait strategy: signal waiting consumers and park briefly
waitStrategy.signalAllWhenBlocking();
LockSupport.parkNanos(1L);
// recompute the minimum consumer sequence
long minSequence = Util.getMinimumSequence(gatingSequences, nextValue);
this.cachedValue = minSequence;
this.nextValue = nextSequence;
}
return nextSequence;
}After publishing, the producer returns the sequence number that consumers can safely read.
Disruptor Consumer Model
Consumers run as EventProcessor instances, each typically bound to a dedicated thread. The core loop is:
Use SequenceBarrier.waitFor() to obtain the highest available sequence for processing.
If a batch start callback is configured, invoke it.
Iterate from the next expected sequence up to the available sequence, fetching each event from the ring buffer and invoking the user‑provided EventHandler.onEvent().
Update the consumer’s own sequence and repeat.
while (true) {
long availableSequence = sequenceBarrier.waitFor(nextSequence);
if (batchStartAware != null) {
batchStartAware.onBatchStart(availableSequence - nextSequence + 1);
}
while (nextSequence <= availableSequence) {
T event = dataProvider.get(nextSequence);
eventHandler.onEvent(event, nextSequence, nextSequence == availableSequence);
nextSequence++;
}
sequence.set(availableSequence);
}The waitFor() method delegates to a WaitStrategy (e.g., YieldingWaitStrategy, BlockingWaitStrategy, SleepingWaitStrategy) that determines how a consumer behaves when no events are currently available.
Key Takeaways
Disruptor’s ring‑buffer eliminates contention by allowing producers to claim slots without locking each write.
Sequence caching reduces the frequency of expensive consumer‑progress checks.
Different wait strategies balance CPU usage and latency according to workload characteristics.
The framework achieves single‑thread throughput of millions of events per second, making it suitable for high‑frequency trading, messaging systems, and other latency‑sensitive applications.
Illustrations
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
