Mastering Disruptor: High‑Performance Java Queue for Producer‑Consumer Systems
This article introduces the open‑source Disruptor framework, explains its core concepts such as Ring Buffer, Sequencer, and Wait Strategies, and provides a step‑by‑step Java demo—including Maven setup, event factory, handlers, and a test case—to illustrate building a high‑throughput, low‑latency in‑memory message queue.
1 Background
In a project we needed a fast in‑memory message queue and chose Disruptor, an open‑source library known for its speed.
2 Disruptor Overview
Disruptor was developed by LMAX, a UK foreign‑exchange trading company, to solve latency problems of traditional memory queues, achieving performance comparable to I/O operations.
Systems built on Disruptor can process six million orders per second on a single thread.
It is a Java framework designed to maximize throughput (TPS) and minimize latency for the producer‑consumer problem.
Disruptor implements a bounded queue, making it suitable for any producer‑consumer scenario.
Beyond finance, Disruptor can significantly improve performance in general applications.
It is more a design pattern than a conventional framework, offering a high‑performance solution for concurrent, buffered, producer‑consumer, or transactional programs.
3 Core Concepts of Disruptor
1. Ring Buffer
The circular buffer that stores events. Since version 3.0 its responsibility is limited to storing and updating data; users can replace it with custom implementations.
2. Sequence
Sequences assign incremental numbers to events, ensuring they are processed in order. A Sequence tracks the progress of a specific consumer.
Preventing false sharing between sequences is a key performance factor.
3. Sequencer
The heart of Disruptor. Implementations such as SingleProducerSequencer and MultiProducerSequencer define the concurrent algorithm that passes data between producers and consumers.
4. Sequence Barrier
Maintains references to the main published sequence of the RingBuffer and the sequences of dependent consumers, determining whether a consumer has events to process.
5. Wait Strategy
Defines how a consumer waits for the next event. Disruptor provides several strategies with different performance characteristics.
6. Event
In Disruptor terminology, the data exchanged between producer and consumer is called an Event. Its type is defined by the user.
7. EventProcessor
Holds a consumer’s Sequence and runs the event‑handling loop.
8. EventHandler
User‑implemented interface that processes events; it is the actual consumer implementation.
9. Producer
Any user code that publishes events to the Disruptor; no specific interface is required.
4 Demo – Step‑by‑Step Implementation
Follow these eight steps to set up Disruptor in a Spring Boot project.
1. Add Maven Dependency
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>2. Define Message Model
@Data
public class MessageModel {
private String message;
}3. Create EventFactory
public class HelloEventFactory implements EventFactory<MessageModel> {
@Override
public MessageModel newInstance() {
return new MessageModel();
}
}4. Implement EventHandler (Consumer)
@Slf4j
public class HelloEventHandler implements EventHandler<MessageModel> {
@Override
public void onEvent(MessageModel event, long sequence, boolean endOfBatch) {
try {
Thread.sleep(1000);
log.info("Consumer starts processing");
if (event != null) {
log.info("Consumed message: {}", event);
}
} catch (Exception e) {
log.info("Consumer failed");
}
log.info("Consumer ends processing");
}
}5. BeanManager for ApplicationContext
@Component
public class BeanManager implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanManager.applicationContext = applicationContext;
}
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);
}
}6. Configure RingBuffer (MQManager)
@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();
}
}7. Service Interface and Implementation (Producer)
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);
}
}
}8. Test Class
@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);
}
}Running the test produces logs that show the producer recording the message, the consumer processing it asynchronously, and the overall flow completing successfully.
5 Summary
The producer‑consumer pattern is common, and many message‑queue solutions can achieve it, but Disruptor implements the queue entirely in memory without locks, which explains its exceptional performance.
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.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
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.
