zio.blocks.streams.queues
Members list
Type members
Classlikes
A blocking MPMC (multi-producer, multi-consumer) queue.
A blocking MPMC (multi-producer, multi-consumer) queue.
Backed by MpmcRingBuffer for the fast path; uses LockSupport.parkNanos for blocking when the buffer is full or empty.
Multiple threads may call offer and take concurrently.
==Single-Waiter Design==
Only one producer and one consumer can be fast-path woken at a time. The queue maintains a single producerWaiter and consumerWaiter volatile slot. When a thread blocks, it registers itself in the appropriate slot and calls LockSupport.parkNanos(this, 1000L) (1 microsecond timeout). When the opposite side has data/space, it unparks the registered waiter. Other waiting threads wake up within 1 microsecond via the timeout and retry.
This design is virtual-thread friendly: parkNanos does not OS-block on virtual threads, allowing bounded re-checks without risk of permanent parking.
==Happens-Before Guarantee==
The pattern producerWaiter = Thread.currentThread() (volatile write) followed by if (closed) return false (volatile read) ensures that a close() call setting closed = true is always visible before the thread parks. This prevents the race where a thread parks after close() has already been called.
==close() Behavior==
close() unparks only the registered producerWaiter and consumerWaiter. Other waiting threads wake up within 1 microsecond via parkNanos timeout and detect the closed flag on retry. This is intentional and documented.
Null elements are not permitted.
Value parameters
- capacity
-
The logical capacity. Rounded up to the next power of two >= 2 internally.
Attributes
- Source
- BlockingMpmcQueue.scala
- Supertypes
A blocking MPSC (multi-producer, single-consumer) queue.
A blocking MPSC (multi-producer, single-consumer) queue.
Backed by MpscRingBuffer for the fast path; uses LockSupport.park and LockSupport.unpark for blocking when the buffer is full or empty.
Multiple threads may call offer concurrently. Only a single thread may call take, drain, isEmpty, or isClosed.
Multi-producer parking: a single producerWaiter volatile slot is used. One producer registers and gets fast-path unpark from consumer. Others use parkNanos(1000) (1µs) to retry — VT-friendly, no starvation.
Null elements are not permitted.
Value parameters
- capacity
-
The logical capacity. Rounded up to the next power of two internally.
Attributes
- Source
- BlockingMpscQueue.scala
- Supertypes
A blocking single-producer single-consumer queue.
A blocking single-producer single-consumer queue.
Backed by SpscRingBuffer for the fast path; uses LockSupport.park and LockSupport.unpark for blocking when the buffer is full or empty.
Two separate waiter slots are maintained — consumerWaiter and producerWaiter — so that each side registers in its own slot without overwriting the other side's registration. A single shared slot would introduce a lost-wakeup race: the producer could overwrite the consumer's registration before the consumer parks, causing the consumer's park to return via stale permit and then clear the producer's registration, leaving the producer permanently blocked.
Null elements are not permitted.
Value parameters
- capacity
-
The logical capacity. Rounded up to the next power of two internally.
Attributes
- Source
- BlockingSpscQueue.scala
- Supertypes