Backend Development 10 min read

Introduction to Disruptor: High‑Performance Java Message Queue with Full Code Demo

This article introduces the open‑source Disruptor library, explains its core concepts such as Ring Buffer, Sequencer, and Wait Strategy, and provides a step‑by‑step Java implementation—including Maven dependency, event model, factory, handler, manager, producer, and test code—demonstrating how to build a fast in‑memory message queue.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Introduction to Disruptor: High‑Performance Java Message Queue with Full Code Demo

Disruptor Introduction

Disruptor is an open‑source Java framework originally developed by LMAX for high‑throughput, low‑latency producer‑consumer scenarios; a single‑threaded system built on it can handle up to 6 million orders per second.

Core Concepts

The library revolves around several key objects:

Ring Buffer – a circular buffer that stores events.

Sequence – tracks progress of consumers and avoids false sharing.

Sequencer – core interface with SingleProducerSequencer and MultiProducerSequencer implementations.

Sequence Barrier – coordinates consumer dependencies.

Wait Strategy – defines how consumers wait for new events.

Event – user‑defined data exchanged between producer and consumer.

EventProcessor, EventHandler, Producer – interfaces for processing and publishing events.

Demo Example (8 Steps)

1. Add Maven dependency:

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>

2. Define the message model:

@Data
public class MessageModel {
    private String message;
}

3. Implement EventFactory :

public class HelloEventFactory implements EventFactory
{
    @Override
    public MessageModel newInstance() {
        return new MessageModel();
    }
}

4. Create an EventHandler (consumer):

@Slf4j
public class HelloEventHandler implements EventHandler
{
    @Override
    public void onEvent(MessageModel event, long sequence, boolean endOfBatch) {
        try {
            Thread.sleep(1000);
            log.info("Consumer start processing");
            if (event != null) {
                log.info("Consumed message: {}", event);
            }
        } catch (Exception e) {
            log.info("Consumer failed");
        }
        log.info("Consumer end processing");
    }
}

5. Provide a bean manager to access Spring context:

@Component
public class BeanManager implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        applicationContext = ctx;
    }
    public static ApplicationContext getApplicationContext() { return applicationContext; }
    public static Object getBean(String name) { return applicationContext.getBean(name); }
    public static
T getBean(Class
clazz) { return applicationContext.getBean(clazz); }
}

6. Configure the Disruptor and expose a RingBuffer bean:

@Configuration
public class MQManager {
    @Bean("messageModel")
    public RingBuffer
messageModelRingBuffer() {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        HelloEventFactory factory = new HelloEventFactory();
        int bufferSize = 1024 * 256; // must be power of 2
        Disruptor
disruptor = new Disruptor<>(factory, bufferSize, executor,
                ProducerType.SINGLE, new BlockingWaitStrategy());
        disruptor.handleEventsWith(new HelloEventHandler());
        disruptor.start();
        return disruptor.getRingBuffer();
    }
}

7. Define a service interface and implementation (producer):

public interface DisruptorMqService {
    void sayHelloMq(String message);
}

@Slf4j
@Component
@Service
public class DisruptorMqServiceImpl implements DisruptorMqService {
    @Autowired
    private RingBuffer
messageModelRingBuffer;
    @Override
    public void sayHelloMq(String message) {
        log.info("record the message: {}", message);
        long sequence = messageModelRingBuffer.next();
        try {
            MessageModel event = messageModelRingBuffer.get(sequence);
            event.setMessage(message);
            log.info("Add message to queue: {}", event);
        } catch (Exception e) {
            log.error("failed to add event", e);
        } finally {
            messageModelRingBuffer.publish(sequence);
        }
    }
}

8. Write a SpringBoot test to publish a message:

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class DemoApplicationTests {
    @Autowired
    private DisruptorMqService disruptorMqService;
    @Test
    public void sayHelloMqTest() throws Exception {
        disruptorMqService.sayHelloMq("消息到了,Hello world!");
        log.info("Message queue sent");
        Thread.sleep(2000);
    }
}

Running the test produces log output confirming the message is recorded, added to the ring buffer, and processed asynchronously by the consumer.

Conclusion

The producer‑consumer pattern is common, and while many message‑queue solutions exist, Disruptor achieves high performance by operating entirely in memory without locks, making it suitable for latency‑critical applications.

Promotional Note

The author invites readers to join his “knowledge planet” for free video tutorials on topics such as Spring Cloud Alibaba and massive data sharding, mentioning that early members can watch for free before prices increase.

JavaBackend Developmentconcurrencymessage queueDisruptorRing Buffer
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login 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.