Understanding Disruptor: Core Concepts, Architecture, and Java Implementation Demo
This article introduces the high‑performance Disruptor library, explains its background, core concepts such as RingBuffer, Sequence, Sequencer, and WaitStrategy, and provides a complete Spring Boot‑based Java demo with code snippets illustrating producers, consumers, and configuration.
01. Background
In a recent project we needed a fast in‑memory message queue and chose LMAX Disruptor instead of Kafka or RabbitMQ because of its superior latency and open‑source nature.
02. Disruptor Introduction
Disruptor is a high‑performance Java framework originally developed by LMAX for low‑latency trading; it can process millions of events per second with minimal I/O‑like delay. It implements a bounded queue designed for the producer‑consumer problem, offering very high throughput and low latency.
03. Core Concepts
The essential domain objects of Disruptor are RingBuffer, Sequence, Sequencer, SequenceBarrier, WaitStrategy, Event, EventProcessor, EventHandler, and Producer.
04. Ring Buffer
The RingBuffer is the central data structure that stores events; since version 3.0 its responsibility is limited to storage and update, and it can be replaced by a custom implementation if needed.
05. Sequence Disruptor
Each event is identified by a monotonically increasing sequence number, which allows tracking of processing progress while avoiding false sharing in CPU caches.
06. Sequencer
The Sequencer interface has two implementations – SingleProducerSequencer and MultiProducerSequencer – that manage the fast, correct hand‑off of data between producers and consumers.
07. Sequence Barrier
SequenceBarrier holds references to the main published sequence of the RingBuffer and to dependent consumer sequences, determining whether a consumer can process more events.
08. Wait Strategy
WaitStrategy defines how a consumer waits for the next event; Disruptor provides several strategies with different performance characteristics.
09. Event
An Event is the user‑defined data object exchanged between producers and consumers; Disruptor does not impose a specific type.
10. EventProcessor
EventProcessor holds a consumer’s Sequence and runs the event loop that invokes the consumer’s handling logic.
11. EventHandler
EventHandler is a user‑implemented interface that processes each Event; it is the concrete consumer implementation.
12. Producer
The Producer is any user code that publishes events to the Disruptor; no specific interface is required.
13. Demo
The following code demonstrates a complete Spring Boot integration:
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.4</version>
</dependency> @Data
public class MessageModel {
private String message;
} public class HelloEventFactory implements EventFactory<MessageModel> {
@Override
public MessageModel newInstance() {
return new MessageModel();
}
} @Slf4j
public class HelloEventHandler implements EventHandler<MessageModel> {
@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 processing failed");
}
log.info("Consumer end processing");
}
} @Configuration
public class MQManager {
@Bean("messageModel")
public RingBuffer<MessageModel> messageModelRingBuffer() {
ExecutorService executor = Executors.newFixedThreadPool(2);
HelloEventFactory factory = new HelloEventFactory();
int bufferSize = 1024 * 256;
Disruptor<MessageModel> disruptor = new Disruptor<>(factory, bufferSize, executor,
ProducerType.SINGLE, new BlockingWaitStrategy());
disruptor.handleEventsWith(new HelloEventHandler());
disruptor.start();
return disruptor.getRingBuffer();
}
} public interface DisruptorMqService {
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);
}
}
} @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);
}
}The test output shows the producer logging the message, the consumer processing it after a short delay, and the overall flow completing successfully.
14. Conclusion
The producer‑consumer pattern is common, but Disruptor implements it in memory without locks, which explains its high efficiency.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.