Mastering Disruptor: Build a High‑Performance Java Message Queue in 8 Steps
This article introduces the Disruptor library, explains its core concepts such as Ring Buffer, Sequencer, and Wait Strategy, and provides a complete eight‑step Spring Boot example with code to create, publish, and consume high‑throughput messages in Java.
Background
In a project we needed a fast message queue and chose Disruptor, an open‑source Java framework known for its extreme speed.
Disruptor Overview
Disruptor was developed by LMAX, a UK foreign‑exchange trading firm, to solve memory‑queue latency and can handle millions of orders per second.
It is a Java framework designed to achieve maximum throughput and minimal latency for the producer‑consumer problem.
Functionally it implements a bounded queue, making it suitable for any producer‑consumer scenario.
LMAX uses it to process 6 million TPS; it can improve performance in many other domains.
Disruptor is more a design pattern than a traditional framework, offering a high‑performance solution for concurrent, buffered, transactional workloads.
GitHub: https://github.com/LMAX-Exchange/disruptor
Core Concepts of Disruptor
The following domain objects map directly to the code implementation.
Ring Buffer
The circular buffer that stores events; since version 3.0 its responsibility is limited to storing and updating data.
Sequence
Sequences are monotonically increasing numbers that identify each event and track consumer progress, avoiding false sharing.
Sequencer
The heart of Disruptor, with implementations
SingleProducerSequencerand
MultiProducerSequencer, defines the fast, correct concurrency algorithm.
Sequence Barrier
Maintains references to the main published sequence and dependent consumer sequences, determining if a consumer can process more events.
Wait Strategy
Specifies how a consumer waits for the next event; Disruptor provides several strategies with different performance characteristics.
Event
Data exchanged between producer and consumer; the type is defined by the user.
EventProcessor
Holds a consumer’s sequence and runs the event loop that invokes the user‑provided handler.
EventHandler
User‑implemented interface that processes each event.
Producer
Any code that publishes events to Disruptor; no specific interface is required.
Example Implementation (8 Steps)
Follow these steps to integrate Disruptor into a Spring Boot project.
Add the Maven dependency:
<code><dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.4</version>
</dependency></code>Create the message model:
<code>/**
* Message body
*/
@Data
public class MessageModel {
private String message;
}</code>Implement the
EventFactory:
<code>public class HelloEventFactory implements EventFactory<MessageModel> {
@Override
public MessageModel newInstance() {
return new MessageModel();
}
}</code>Implement the consumer (
EventHandler):
<code>@Slf4j
public class HelloEventHandler implements EventHandler<MessageModel> {
@Override
public void onEvent(MessageModel event, long sequence, boolean endOfBatch) {
try {
Thread.sleep(1000); // simulate async processing
log.info("Consumer starts processing");
if (event != null) {
log.info("Consumed message: {}", event);
}
} catch (Exception e) {
log.info("Consumer processing failed");
}
log.info("Consumer ends processing");
}
}</code>Create a bean manager to obtain Spring beans:
<code>/** Get Spring beans */
@Component
public class BeanManager implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.applicationContext = ctx;
}
public static ApplicationContext getApplicationContext() { return applicationContext; }
public static Object getBean(String name) { return applicationContext.getBean(name); }
public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); }
}</code>Configure the Disruptor bean:
<code>@Configuration
public class MQManager {
@Bean("messageModel")
public RingBuffer<MessageModel> messageModelRingBuffer() {
ExecutorService executor = Executors.newFixedThreadPool(2);
HelloEventFactory factory = new HelloEventFactory();
int bufferSize = 1024 * 256; // must be power of two
Disruptor<MessageModel> disruptor = new Disruptor<>(factory, bufferSize, executor,
ProducerType.SINGLE, new BlockingWaitStrategy());
disruptor.handleEventsWith(new HelloEventHandler());
disruptor.start();
return disruptor.getRingBuffer();
}
}
</code>Define the service interface and implementation (producer):
<code>public interface DisruptorMqService {
/** Send a message */
void sayHelloMq(String message);
}
@Slf4j
@Component
@Service
public class DisruptorMqServiceImpl implements DisruptorMqService {
@Autowired
private RingBuffer<MessageModel> 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);
}
}
}
</code>Write a Spring Boot test to publish a message:
<code>@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class DemoApplicationTests {
@Autowired
private DisruptorMqService disruptorMqService;
@Test
public void sayHelloMqTest() throws Exception {
disruptorMqService.sayHelloMq("Message arrived, Hello world!");
log.info("Message queue sent");
Thread.sleep(2000); // ensure async processing
}
}
</code>Test output demonstrates the producer logging the message, the consumer processing it asynchronously, and the overall flow completing without blocking.
Conclusion
The producer‑consumer pattern is common, and many message‑queue solutions can achieve similar results, but Disruptor implements it entirely in memory with a lock‑free design, which is why it delivers such high efficiency.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.