Unlock Ultra‑Fast Messaging with Disruptor: A Hands‑On Java Guide
This article introduces the high‑performance Disruptor library, explains its core concepts such as Ring Buffer, Sequence, and Wait Strategy, and provides a step‑by‑step Java demo—including Maven setup, event model, producer, consumer, and test—showcasing how to build a lock‑free in‑memory message queue.
Disruptor Introduction
Disruptor is a high‑performance queue developed by LMAX, a UK foreign‑exchange trading company, designed to solve memory‑queue latency issues, achieving throughput comparable to I/O operations.
Based on Disruptor, a single‑threaded system can handle 6 million orders per second; it gained industry attention after a 2010 QCon talk.
Disruptor is an open‑source Java framework aimed at maximizing throughput (TPS) and minimizing latency for the producer‑consumer problem.
It implements a bounded queue, making it suitable for any producer‑consumer scenario.
Disruptor is a core component of LMAX’s online trading platform, enabling 6 million TPS; it can boost performance in many other applications.
More than a framework, Disruptor represents a design approach that dramatically improves performance for programs involving concurrency, buffers, producer‑consumer models, or transaction processing.
GitHub repository: https://github.com/LMAX-Exchange/disruptor
Core Concepts of Disruptor
Understanding the core concepts reveals how Disruptor works; the following domain objects map directly to code implementations.
1. Ring Buffer
A circular buffer that, since version 3.0, mainly stores and updates events exchanged via Disruptor; users can provide custom implementations.
2. Sequence
Sequences assign incremental numbers to events, ensuring processing proceeds in order; they also prevent false sharing between CPU caches.
3. Sequencer
The true core, with SingleProducerSequencer and MultiProducerSequencer implementations, defines the concurrent algorithm for data transfer between producers and consumers.
4. Sequence Barrier
Maintains references to the main published sequence of the RingBuffer and dependent consumer sequences, determining whether a consumer can process more events.
5. Wait Strategy
Specifies how a consumer waits for the next event; Disruptor provides several strategies with different performance characteristics.
6. Event
Events are the data exchanged between producers and consumers; their type is defined by the user.
7. EventProcessor
Holds a consumer’s sequence and runs the event loop that invokes the consumer’s processing logic.
8. EventHandler
User‑implemented interface that processes events; it is the concrete consumer.
9. Producer
Any user code that publishes events to Disruptor; no specific interface is required.
Demo Example
Follow these eight steps to get Disruptor up and running.
1. Add Maven dependency
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>2. Message model
@Data
public class MessageModel {
private String message;
}3. EventFactory
public class HelloEventFactory implements EventFactory<MessageModel> {
@Override
public MessageModel newInstance() {
return new MessageModel();
}
}4. 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 processing failed");
}
log.info("Consumer ends processing");
}
}5. BeanManager
@Component
public class BeanManager implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.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. 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("Added message to queue: {}", event);
} catch (Exception e) {
log.error("failed to add event to messageModelRingBuffer", 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);
}
}Test output shows logging of message publishing and consumer processing.
Conclusion
The producer‑consumer pattern is common; Disruptor implements it in memory without locks, which explains its high efficiency.
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.
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
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.
