Package org.jgroups.util
Class ConcurrentBlockingRingBuffer<T>
- java.lang.Object
-
- org.jgroups.util.ConcurrentBlockingRingBuffer<T>
-
- All Implemented Interfaces:
java.lang.Iterable<T>,java.util.Collection<T>,java.util.concurrent.BlockingQueue<T>,java.util.Queue<T>
public class ConcurrentBlockingRingBuffer<T> extends java.lang.Object implements java.util.concurrent.BlockingQueue<T>MPSC queue, based on a ring buffer implementation which optionally blocks on adding or removing of elements.
The main fields are read-index (ri), write-index (wi) and size (all AtomicIntegers). Producers change wi and size, the single consumer changes ri and size.
A producer tries to increment size. If unsuccessful, it drops the message (or blocks). If successful, it increments wi and writes the element to array[wi]. If size was incremented from 0 -> 1, a producer also wakes up the consumer.
The single consumer tries to remove size elements (drainTo() or poll()), but returns when a null element is found (see below). It then decrements size by the number of removed elements (N for drainTo() and 1 for a successful poll()). If no elements are in the ring buffer, the consumer blocks (if configured), until it is woken up by a producer adding the first element to the empty queue.
Note that this class is designed for a single consumer and has undefined behavior if multiple consumers are used.
There is a special case that has the consumer busy-polling (ri=wi=1): assume we have producers P1-P3, each adding an element concurrently. P3 successfully incremented size from 0->1 and set wi=3. P2 also incremented size from 1->2 and set wi=1, but didn't yet write to the array. P3 incremented size from 2->3 and set wi=2, but also didn't write to the array yet. P1 woke up the consumer, but the consumer saw array[1]=null, array[2]=null, array[3]=el3 (written by P3). The consumer therefore returns on the first element because it is null, but continues looping because size=3. Only when P1 and P2 write their respective elements will the consumer be able to make progress.- Since:
- 5.5.0
- Author:
- Bela Ban
-
-
Field Summary
Fields Modifier and Type Field Description protected java.util.concurrent.atomic.AtomicReferenceArray<T>arrayprotected booleanblock_on_emptyprotected booleanblock_on_fullprotected intcapacityprotected static java.util.function.IntUnaryOperatorDECRprotected static java.util.function.IntBinaryOperatorDECR_DELTAprotected java.util.function.IntUnaryOperatorINCRprotected java.util.function.IntUnaryOperatorINCR_INDEXprotected java.util.concurrent.locks.Locklockprotected java.util.concurrent.locks.Conditionnot_emptyprotected java.util.concurrent.locks.Conditionnot_fullprotected intriprotected java.util.concurrent.atomic.AtomicIntegersizeprotected java.util.concurrent.atomic.AtomicIntegerwi
-
Constructor Summary
Constructors Constructor Description ConcurrentBlockingRingBuffer(int capacity)ConcurrentBlockingRingBuffer(int capacity, boolean block_on_empty, boolean block_on_full)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description booleanadd(T t)booleanaddAll(java.util.Collection<? extends T> c)protected intadvance(int idx)protected intadvance(int idx, int delta)intcapacity()voidclear()booleancontains(java.lang.Object o)booleancontainsAll(java.util.Collection<?> c)intdrainTo(java.util.Collection<? super T> c)intdrainTo(java.util.Collection<? super T> c, int max)Telement()booleanisEmpty()java.util.Iterator<T>iterator()booleanoffer(T t)booleanoffer(T t, long timeout, java.util.concurrent.TimeUnit unit)Tpeek()Tpoll()Tpoll(long timeout, java.util.concurrent.TimeUnit unit)voidput(T t)intremainingCapacity()Tremove()booleanremove(java.lang.Object o)booleanremoveAll(java.util.Collection<?> c)booleanremoveIf(java.util.function.Predicate<? super T> filter)booleanretainAll(java.util.Collection<?> c)protected voidsignalNotEmpty()protected voidsignalNotFull()intsize()Ttake()java.lang.Object[]toArray()<T1> T1[]toArray(T1[] a)java.lang.StringtoString()-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
-
-
-
Field Detail
-
capacity
protected final int capacity
-
array
protected final java.util.concurrent.atomic.AtomicReferenceArray<T> array
-
wi
protected final java.util.concurrent.atomic.AtomicInteger wi
-
ri
protected int ri
-
size
protected final java.util.concurrent.atomic.AtomicInteger size
-
block_on_empty
protected final boolean block_on_empty
-
block_on_full
protected final boolean block_on_full
-
lock
protected final java.util.concurrent.locks.Lock lock
-
not_empty
protected final java.util.concurrent.locks.Condition not_empty
-
not_full
protected final java.util.concurrent.locks.Condition not_full
-
INCR
protected final java.util.function.IntUnaryOperator INCR
-
INCR_INDEX
protected final java.util.function.IntUnaryOperator INCR_INDEX
-
DECR
protected static final java.util.function.IntUnaryOperator DECR
-
DECR_DELTA
protected static final java.util.function.IntBinaryOperator DECR_DELTA
-
-
Method Detail
-
capacity
public int capacity()
-
put
public void put(T t) throws java.lang.InterruptedException
- Specified by:
putin interfacejava.util.concurrent.BlockingQueue<T>- Throws:
java.lang.InterruptedException
-
add
public boolean add(T t)
-
addAll
public boolean addAll(java.util.Collection<? extends T> c)
- Specified by:
addAllin interfacejava.util.Collection<T>
-
offer
public boolean offer(T t)
-
offer
public boolean offer(T t, long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException
- Specified by:
offerin interfacejava.util.concurrent.BlockingQueue<T>- Throws:
java.lang.InterruptedException
-
clear
public void clear()
- Specified by:
clearin interfacejava.util.Collection<T>
-
isEmpty
public boolean isEmpty()
- Specified by:
isEmptyin interfacejava.util.Collection<T>
-
poll
public T poll(long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException
- Specified by:
pollin interfacejava.util.concurrent.BlockingQueue<T>- Throws:
java.lang.InterruptedException
-
drainTo
public int drainTo(java.util.Collection<? super T> c, int max)
- Specified by:
drainToin interfacejava.util.concurrent.BlockingQueue<T>
-
drainTo
public int drainTo(java.util.Collection<? super T> c)
- Specified by:
drainToin interfacejava.util.concurrent.BlockingQueue<T>
-
take
public T take() throws java.lang.InterruptedException
- Specified by:
takein interfacejava.util.concurrent.BlockingQueue<T>- Throws:
java.lang.InterruptedException
-
remove
public boolean remove(java.lang.Object o)
-
containsAll
public boolean containsAll(java.util.Collection<?> c)
- Specified by:
containsAllin interfacejava.util.Collection<T>
-
contains
public boolean contains(java.lang.Object o)
-
iterator
public java.util.Iterator<T> iterator()
-
toArray
public java.lang.Object[] toArray()
- Specified by:
toArrayin interfacejava.util.Collection<T>
-
toArray
public <T1> T1[] toArray(T1[] a)
- Specified by:
toArrayin interfacejava.util.Collection<T>
-
removeAll
public boolean removeAll(java.util.Collection<?> c)
- Specified by:
removeAllin interfacejava.util.Collection<T>
-
removeIf
public boolean removeIf(java.util.function.Predicate<? super T> filter)
- Specified by:
removeIfin interfacejava.util.Collection<T>
-
retainAll
public boolean retainAll(java.util.Collection<?> c)
- Specified by:
retainAllin interfacejava.util.Collection<T>
-
size
public int size()
- Specified by:
sizein interfacejava.util.Collection<T>
-
remainingCapacity
public int remainingCapacity()
- Specified by:
remainingCapacityin interfacejava.util.concurrent.BlockingQueue<T>
-
toString
public java.lang.String toString()
- Overrides:
toStringin classjava.lang.Object
-
advance
protected int advance(int idx)
-
advance
protected int advance(int idx, int delta)
-
signalNotEmpty
protected void signalNotEmpty()
-
signalNotFull
protected void signalNotFull()
-
-