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.

FunTester
FunTester
FunTester
Using LMAX Disruptor for High‑Performance Event Processing in Java

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaconcurrencyDisruptorhigh performanceQueue
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.