Using LMAX Disruptor for High‑Performance Event Processing in Java
This article explains how to replace Java's LinkedBlockingQueue with the high‑throughput LMAX Disruptor library, covering dependency setup, event definition, Disruptor creation, producer and consumer implementations, handler configuration, startup/shutdown procedures, and provides both Java and Groovy demo code.
Dependencies
Include the Disruptor library (e.g.,
implementation group: 'com.lmax', name: 'disruptor', version: '3.4.2') in your Gradle build; version 3+ is recommended for Lambda support.
Event Object
Define a simple event class (e.g., FunEvent) with an id field and getter/setter methods to avoid direct field assignment and improve code clarity.
public static class FunEvent {
String id;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
}Disruptor Creation
Create a Disruptor<FunEvent> instance by providing an event factory, ring buffer size (power of two), a thread‑factory, producer type (single or multi), and a wait strategy such as YieldingWaitStrategy.
Disruptor<FunEvent> disruptor = new Disruptor<>(
FunEvent::new,
1024 * 1024,
ThreadPoolUtil.getFactory(),
ProducerType.MULTI,
new YieldingWaitStrategy()
);Producer
Publish events by reserving a sequence, setting the event data, and then publishing the sequence. With Lambda support the code can be simplified to a single publishEvent call.
ringBuffer.publishEvent((event, sequence) -> event.setId(StringUtil.getString(10)));Consumer
Implement EventHandler<FunEvent> or WorkHandler<FunEvent> to process events. The handler can define onEvent(FunEvent event, long sequence, boolean endOfBatch) for single‑consumer mode or onEvent(FunEvent event) for worker‑pool mode.
private static class FunEventHandler implements EventHandler<FunEvent>, WorkHandler<FunEvent> {
public void onEvent(FunEvent event, long sequence, boolean endOfBatch) {
output("Consume message:" + event.getId() + " " + sequence);
}
public void onEvent(FunEvent event) {
output("Consume message:" + event.getId());
}
}Handler Configuration
Register a single consumer with disruptor.handleEventsWith(new FunEventHandler()) or multiple consumers with
disruptor.handleEventsWithWorkerPool(new FunEventHandler(), new FunEventHandler()). Each EventHandlerGroup consumes every published event; slow handlers can block others.
Startup and Shutdown
After configuring handlers, start the Disruptor with disruptor.start(). When finished, call disruptor.shutdown() to stop producing and allow remaining events to be processed.
Java Demo
public static void main(String[] args) {
Disruptor<FunEvent> disruptor = new Disruptor<>(
FunEvent::new,
1024 * 1024,
ThreadPoolUtil.getFactory(),
ProducerType.MULTI,
new YieldingWaitStrategy()
);
disruptor.handleEventsWithWorkerPool(new FunEventHandler(), new FunEventHandler());
disruptor.handleEventsWith(new FunEventHandler());
disruptor.start();
RingBuffer<FunEvent> ringBuffer = disruptor.getRingBuffer();
for (int i = 0; i < 3; i++) {
ringBuffer.publishEvent((event, sequence) -> event.setId(StringUtil.getString(10)));
}
sleep(5.0);
disruptor.shutdown();
}The console output shows each message being consumed twice, illustrating how multiple EventHandlerGroup instances each receive the same events.
Groovy Async Version
public static void main(String[] args) {
Disruptor<FunEvent> disruptor = new Disruptor<>(
FunEvent::new,
1024 * 1024,
ThreadPoolUtil.getFactory(),
ProducerType.MULTI,
new YieldingWaitStrategy()
)
disruptor.handleEventsWithWorkerPool(new FunEventHandler(), new FunEventHandler())
disruptor.handleEventsWith(new FunEventHandler())
disruptor.start()
RingBuffer<FunEvent> ringBuffer = disruptor.getRingBuffer();
def funtester = {
fun {
100.times { ringBuffer.publishEvent((event, sequence) -> event.setId(StringUtil.getString(10))) }
}
}
10.times { funtester() }
sleep(5.0)
disruptor.shutdown()
}This Groovy example demonstrates the same Disruptor setup with a more concise syntax for publishing events.
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.
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.
