Skip to content
jac18281828 edited this page Dec 23, 2015 · 23 revisions

Conversant ConcurrentQueue and Disruptor BlockingQueue

Disruptor is the highest performing intra-thread transfer mechanism available in Java. Conversant Disruptor is the highest performing implementation of this type of ring buffer queue because it has almost no overhead and it exploits a particularly simple design.

Introduction

The Conversant Disruptor is designed to be fast by exploiting only cache level optimizations while keeping the overall approach to thread transfers direct and simple. The main advantage of the Conversant Disruptor over other Disruptor implementations is that it is based on the Java BlockingQueue interface so existing software can be immediately adapted to use this disruptor without significant programming changes.

Conversant Disruptor is a drop in replacement for ArrayBlockingQueue with an order of magnitude better performance. In comparison with LinkedTransferQueue this disruptor implementation is roughly two times faster and does not allocate any objects internally. Given that LinkedTransferQueue is state of the art in Java performance, Conversant Disruptor may yield significant performance improvements for applications that rely on fast intra-thread transfers.

Conversant Disruptor is capable of 4ns intra-thread transfers for push-pull senarios and 20ns multi-thread transfers in an 1 to N senario. The "Disruptor" approach is sensitive to huge numbers of threads and will not exibit good performance if your application exploits hundreds or thousands of waiting threads. Waiting threads will spin-lock the CPU. From a performance perspective, designing applications to exploit hundreds or thousands of waiting threads is never advisable.

Getting Started

Getting started with Conversant Disruptor is easy! Simply download and build the Java package. Once you have included the dependency in your project, you may use the Conversant Disruptor as you would any other Java BlockingQueue.

Conversant Disruptor comes in two flavors: push-pull and multithread. Push-pull is designed to work in the special case where there is only one producer thread and one consumer thread present. It is critical that this requirement is met, because the performance advantage of the push-pull impelmentation comes at the cost of not being thread safe for multiple producer or consumer threads. If you access the push pull implementation with multiple simultaneous threads data will be lost.

The multithread implementation provides a full blocking queue implementation which may be used with multiple producer and consumer threads, however keep in mind that performance is degraded as the number of threads increase. This is a natural artifact of the disruptor strategy because most of performance comes from a particular thread obtaining the shared context by chance. The number of threads should be kept to a minimum. Ultimately there is a 5x performance penalty for using the multithread version even for the simplest push-pull senario.

Conversant Diruptor provides four different implementations. The ConcurrentQueue implementations provide the rudimentary queuing functionality without any of the timing or waiting functionality. This is useful if you are developing an application that will utilize spin locking or where timed waiting is not needed. The 'BlockingQueue' implementations provide full support of the Java BlockingQueue interface including blocking and waiting timing support.

Clone this wiki locally