A high-performance, non-blocking SPMC (Single-Producer Multi-Consumer) ring buffer for generic reference types.
The producer uses index-based capacity checking with a cached producerLimit derived from consumerIndex. On the fast path, the producer avoids reading the volatile consumerIndex entirely; the slow path re-reads it to refresh the limit. The consumer side uses a CAS loop on consumerIndex to allow multiple consumer threads to safely dequeue elements concurrently.
'''Design:''' Consumers do not clear (null) array slots after reading. Instead, the producer freely overwrites slots once index-based capacity checking confirms the consumer has advanced past them. This eliminates the producer-consumer slot-clearing race that would otherwise occur in SPMC when a consumer CAS-claims a slot but hasn't yet nulled it. The element's validity is determined solely by comparing producerIndex and consumerIndex, never by null-checking slots.
Optimized for SPMC: exactly one producer thread and any number of consumer threads may access the buffer concurrently. Using multiple producer threads results in undefined behavior.
Null elements are not permitted. offer(null) throws NullPointerException.
Value parameters
- capacity
-
the buffer capacity, must be a positive power of two
Attributes
- Companion
- object
- Source
- SpmcRingBuffer.scala
- Graph
-
- Supertypes
Members list
Value members
Concrete methods
Returns true if the buffer contains no elements (approximate under concurrency).
Returns true if the buffer contains no elements (approximate under concurrency).
The value is a snapshot and may be stale by the time the caller acts on it.
Attributes
- Source
- SpmcRingBuffer.scala
Returns true if the buffer is full (approximate under concurrency).
Returns true if the buffer is full (approximate under concurrency).
The value is a snapshot and may be stale by the time the caller acts on it.
Attributes
- Source
- SpmcRingBuffer.scala
Tries to insert an element into the buffer without blocking.
Tries to insert an element into the buffer without blocking.
Uses index-based capacity checking with a cached producerLimit derived from consumerIndex. On the fast path, the producer avoids reading the volatile consumerIndex. When the cached limit is reached, the slow path re-reads consumerIndex to refresh it.
Value parameters
- a
-
the element to insert; must not be
null
Attributes
- Returns
-
trueif the element was successfully inserted,falseif the buffer is full - Throws
-
java.lang.NullPointerException
if the element is
null - Note
-
Must be called from the producer thread only.
- Source
- SpmcRingBuffer.scala
Returns the number of elements currently in the buffer (approximate under concurrency).
Returns the number of elements currently in the buffer (approximate under concurrency).
The value is a snapshot and may be stale by the time the caller acts on it.
Attributes
- Source
- SpmcRingBuffer.scala
Tries to remove an element from the buffer without blocking.
Tries to remove an element from the buffer without blocking.
Multiple consumer threads may call this method concurrently. Each consumer reads the current consumerIndex, checks against producerIndex to detect an empty buffer, reads the element optimistically, then attempts a CAS on consumerIndex to claim the slot. Reading the element before the CAS is critical: it ensures the consumer has the value before the producer can overwrite the slot. If the CAS fails, another consumer won and the read is discarded; the loop retries. Consumers do not clear slots; the producer overwrites them on the next lap.
Attributes
- Returns
-
the element, or
nullif the buffer is empty - Note
-
Safe to call from any consumer thread concurrently.
- Source
- SpmcRingBuffer.scala
Concrete fields
Attributes
- Source
- SpmcRingBuffer.scala
Inherited fields
Attributes
- Inherited from:
- SpmcConsumerFields (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad0 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad1 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcPad2 (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcProducerFields (hidden)
- Source
- SpmcRingBuffer.scala
Attributes
- Inherited from:
- SpmcProducerFields (hidden)
- Source
- SpmcRingBuffer.scala