Top Description Inners Fields Constructors Methods
io.reactivex.internal.queue

public final Class MpscLinkedQueue<T>

extends Object
implements SimplePlainQueue<T>
Class Inheritance
All Implemented Interfaces
io.reactivex.internal.fuseable.SimplePlainQueue, io.reactivex.internal.fuseable.SimpleQueue
Type Parameters
<T>
the contained value type
Imports
java.util.concurrent.atomic.AtomicReference, io.reactivex.annotations.Nullable, io.reactivex.internal.fuseable.SimplePlainQueue

A multi-producer single consumer unbounded queue.

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv static class

Field Summary

Modifier and TypeField and Description
private final AtomicReference<MpscLinkedQueue.LinkedQueueNode<T>>
private final AtomicReference<MpscLinkedQueue.LinkedQueueNode<T>>

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public void
clear()

Implements io.reactivex.internal.fuseable.SimpleQueue.clear.

Removes all enqueued items from this queue.
public boolean
isEmpty()

Implements io.reactivex.internal.fuseable.SimpleQueue.isEmpty.

Returns true if the queue is empty.
pack-priv MpscLinkedQueue.LinkedQueueNode<T>
pack-priv MpscLinkedQueue.LinkedQueueNode<T>
pack-priv MpscLinkedQueue.LinkedQueueNode<T>
public boolean
offer(final T
the value to enqueue, not null
e
)

Implements io.reactivex.internal.fuseable.SimpleQueue.offer.

Atomically enqueue a single.
public boolean
offer(T
the first value to enqueue, not null
v1
,
T
the second value to enqueue, not null
v2
)

Implements io.reactivex.internal.fuseable.SimpleQueue.offer.

Atomically enqueue two values.
public T
poll()

Implements io.reactivex.internal.fuseable.SimplePlainQueue.poll.

Tries to dequeue a value (non-null) or returns null if the queue is empty.
pack-priv void
pack-priv MpscLinkedQueue.LinkedQueueNode<T>
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

consumerNodeback to summary
private final AtomicReference<MpscLinkedQueue.LinkedQueueNode<T>> consumerNode
producerNodeback to summary
private final AtomicReference<MpscLinkedQueue.LinkedQueueNode<T>> producerNode

Constructor Detail

MpscLinkedQueueback to summary
public MpscLinkedQueue()

Method Detail

clearback to summary
public void clear()

Implements io.reactivex.internal.fuseable.SimpleQueue.clear.

Doc from io.reactivex.internal.fuseable.SimpleQueue.clear.

Removes all enqueued items from this queue.

Annotations
@Override
isEmptyback to summary
public boolean isEmpty()

Implements io.reactivex.internal.fuseable.SimpleQueue.isEmpty.

Doc from io.reactivex.internal.fuseable.SimpleQueue.isEmpty.

Returns true if the queue is empty.

Note however that due to potential fused functions in poll() it is possible this method returns false but then poll() returns null because the fused function swallowed the available item(s).

Implementation Notes


Queue is empty when producerNode is the same as consumerNode. An alternative implementation would be to observe the producerNode.value is null, which also means an empty queue because only the consumerNode.value is allowed to be null.

Returns:boolean

true if the queue is empty

Annotations
@Override
lpConsumerNodeback to summary
pack-priv MpscLinkedQueue.LinkedQueueNode<T> lpConsumerNode()
lvConsumerNodeback to summary
pack-priv MpscLinkedQueue.LinkedQueueNode<T> lvConsumerNode()
lvProducerNodeback to summary
pack-priv MpscLinkedQueue.LinkedQueueNode<T> lvProducerNode()
offerback to summary
public boolean offer(final T e)

Implements io.reactivex.internal.fuseable.SimpleQueue.offer.

Doc from io.reactivex.internal.fuseable.SimpleQueue.offer.

Atomically enqueue a single.

IMPLEMENTATION NOTES:
Offer is allowed from multiple threads.
Offer allocates a new node and:

  1. Swaps it atomically with current producer node (only one producer 'wins')
  2. Sets the new node as the node following from the swapped producer node
This works because each producer is guaranteed to 'plant' a new node and link the old node. No 2 producers can get the same producer node as part of XCHG guarantee.
Parameters
e:T

the value to enqueue, not null

Returns:boolean

true if successful, false if the value was not enqueued likely due to reaching the queue capacity)

Annotations
@Override
See Also
java.util.Queue#offer(java.lang.Object)
offerback to summary
public boolean offer(T v1, T v2)

Implements io.reactivex.internal.fuseable.SimpleQueue.offer.

Doc from io.reactivex.internal.fuseable.SimpleQueue.offer.

Atomically enqueue two values.

Parameters
v1:T

the first value to enqueue, not null

v2:T

the second value to enqueue, not null

Returns:boolean

true if successful, false if the value was not enqueued likely due to reaching the queue capacity)

Annotations
@Override
pollback to summary
public T poll()

Implements io.reactivex.internal.fuseable.SimplePlainQueue.poll.

Doc from io.reactivex.internal.fuseable.SimpleQueue.poll.

Tries to dequeue a value (non-null) or returns null if the queue is empty.

If the producer uses offer(Object, Object) and when polling in pairs, if the first poll() returns a non-null item, the second poll() is guaranteed to return a non-null item as well.

IMPLEMENTATION NOTES:
Poll is allowed from a SINGLE thread.
Poll reads the next node from the consumerNode and:

  1. If it is null, the queue is assumed empty (though it might not be).
  2. If it is not null set it as the consumer node and return it's now evacuated value.
This means the consumerNode.value is always null, which is also the starting point for the queue. Because null values are not allowed to be offered this is the only node with it's value set to null at any one time.
Returns:T

the item or null to indicate an empty queue

Annotations
@Nullable
@Override
See Also
java.util.Queue#poll()
spConsumerNodeback to summary
pack-priv void spConsumerNode(MpscLinkedQueue.LinkedQueueNode<T> node)
xchgProducerNodeback to summary
pack-priv MpscLinkedQueue.LinkedQueueNode<T> xchgProducerNode(MpscLinkedQueue.LinkedQueueNode<T> node)
io.reactivex.internal.queue back to summary

pack-priv final Class MpscLinkedQueue.LinkedQueueNode<E>

extends AtomicReference<MpscLinkedQueue.LinkedQueueNode<E>>
Class Inheritance

Field Summary

Modifier and TypeField and Description
private static final long
private E

Constructor Summary

AccessConstructor and Description
pack-priv
pack-priv

Method Summary

Modifier and TypeMethod and Description
public E

Returns:

value
getAndNullValue
()

Gets the current value and nulls out the reference to it from this node.

public E
public MpscLinkedQueue.LinkedQueueNode<E>
public void
public void
spValue(E newValue)

Inherited from java.util.concurrent.atomic.AtomicReference:
accumulateAndGetcompareAndExchangecompareAndExchangeAcquirecompareAndExchangeReleasecompareAndSetgetgetAcquiregetAndAccumulategetAndSetgetAndUpdategetOpaquegetPlainlazySetsetsetOpaquesetPlainsetReleasetoStringupdateAndGetweakCompareAndSetweakCompareAndSetAcquireweakCompareAndSetPlainweakCompareAndSetReleaseweakCompareAndSetVolatile

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Hides java.util.concurrent.atomic.AtomicReference.serialVersionUID.

valueback to summary
private E value

Hides java.util.concurrent.atomic.AtomicReference.value.

Constructor Detail

LinkedQueueNodeback to summary
pack-priv LinkedQueueNode()
LinkedQueueNodeback to summary
pack-priv LinkedQueueNode(E val)

Method Detail

getAndNullValueback to summary
public E getAndNullValue()

Gets the current value and nulls out the reference to it from this node.

Returns:E

value

lpValueback to summary
public E lpValue()
lvNextback to summary
public MpscLinkedQueue.LinkedQueueNode<E> lvNext()
soNextback to summary
public void soNext(MpscLinkedQueue.LinkedQueueNode<E> n)
spValueback to summary
public void spValue(E newValue)