javax.realtime
Class WaitFreeReadQueue

java.lang.Object
  extended by javax.realtime.WaitFreeReadQueue

public class WaitFreeReadQueue
extends java.lang.Object

A queue that can be non-blocking for consumers. The WaitFreeReadQueue class is intended for single-reader multiple-writer communication, although it may also be used (with care) for multiple readers. A reader is generally an instance of NoHeapRealtimeThread, and the writers are generally regular Java threads or heap-using real-time threads or schedulable objects. Communication is through a bounded buffer of Objects that is managed first-in-first-out. The principal methods for this class are write and read

For convenience, and to avoid requiring a reader to poll until the queue is non-empty, this class also supports instances that can be accessed by a reader that blocks on queue empty. To obtain this behavior, the reader needs to invoke the waitForData() method on a queue that has been constructed with a notify parameter set to true.

WaitFreeReadQueue is one of the classes allowing NoHeapRealtimeThreads and regular Java threads to synchronize on an object without the risk of a NoHeapRealtimeThread incurring Garbage Collector latency due to priority inversion avoidance management.

Incompatibility with V1.0: Three exceptions previously thrown by the constructor have been deleted. These are

These exceptions were in error. Their deletion may cause compile-time errors in code using the previous constructor. The repair is to remove the exceptions from the catch clause around the constructor invocation.


Constructor Summary
WaitFreeReadQueue(int maximum, boolean notify)
          Constructs a queue containing up to maximum elements in immortal memory.
WaitFreeReadQueue(int maximum, MemoryArea memory, boolean notify)
          Constructs a queue containing up to maximum elements in memory.
WaitFreeReadQueue(java.lang.Runnable writer, java.lang.Runnable reader, int maximum, MemoryArea memory)
          Constructs a queue containing up to maximum elements in memory.
WaitFreeReadQueue(java.lang.Runnable writer, java.lang.Runnable reader, int maximum, MemoryArea memory, boolean notify)
          Constructs a queue containing up to maximum elements in memory.
 
Method Summary
 void clear()
          Sets this to empty.
 boolean isEmpty()
          Queries the queue to determine if this is empty.
 boolean isFull()
          Queries the system to determine if this is full.
 java.lang.Object read()
          Reads the least recently inserted element from the queue and returns it as the result, unless the queue is empty.
 int size()
          Queries the queue to determine the number of elements in this.
 void waitForData()
          If this is empty block until a writer inserts an element.
 void write(java.lang.Object object)
          A synchronized and blocking write.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

WaitFreeReadQueue

public WaitFreeReadQueue(java.lang.Runnable writer,
                         java.lang.Runnable reader,
                         int maximum,
                         MemoryArea memory,
                         boolean notify)
Constructs a queue containing up to maximum elements in memory. The queue has an unsynchronized and nonblocking read() method and a synchronized and blocking write() method.

The writer and reader parameters, if non-null, are checked to insure that they are compatible with the MemoryArea specified by memory (if non-null.) If memory is null and both Runnables are non-null, the constructor will select the nearest common scoped parent memory area, or if there is no such scope it will use immortal memory. If all three parameters are null, the queue will be allocated in immortal memory.

reader and writer are not necessarily the only threads or schedulable objects that will access the queue; moreover, there is no check that they actually access the queue at all.

Note: that the wait free queue's internal queue is allocated in memory, but the memory area of the wait free queue instance itself is determined by the current allocation context.

Parameters:
writer - An instance of Runnable or null.
reader - An instance of Runnable or null.
maximum - The maximum number of elements in the queue.
memory - The MemoryArea in which internal elements are allocated.
notify - A flag that establishes whether a reader is notified when the queue becomes non-empty.
Throws:
java.lang.IllegalArgumentException - Thrown if an argument holds an invalid value. The writer argument must be null, a reference to a Thread, or a reference to a schedulable object (a RealtimeThread, or an AsyncEventHandler.) The reader argument must be null, a reference to a Thread, or a reference to a schedulable object. The maximum argument must be greater than zero.
InnaccessibleAreaException - Thrown if memory is a scoped memory that is not on the caller's scope stack.
MemoryScopeException - Thrown if either reader or writer is non-null and the memory argument is not compatible with reader and writer with respect to the assignment and access rules for memory areas.
Mackinac comments:
The specification declared writer and reader as Thread. This is inconsistent with the IllegalArgumentException comment. It has been replaced by Runnable, as for the WaitFreeWriteQueue.

The WaitFreeReadQueue must contain a reference to the internal queue. In addition, the readers and writers must be able to access the WaitFreeReadQueue to use it. Hence, the best location for the internal queue is the same area as the WaitFreeReadQueue (e.g. the current allocation context). Mackinac will always choose that space, unless a memory area is explicitly given.

Checks on reader and writer are not clearly defined in the specification. Mackinac ensures that the writer cannot produce objects that are not storable in the internal queue if it remains in the memory area declared while constructing the writer. For the reader, we are only concerned by the read check. Hence, a problem is reported only if the area is the Heap and if the reader is an NHRT or a noheap AsyncEventHandler.


WaitFreeReadQueue

public WaitFreeReadQueue(java.lang.Runnable writer,
                         java.lang.Runnable reader,
                         int maximum,
                         MemoryArea memory)
Constructs a queue containing up to maximum elements in memory. The queue has an unsynchronized and nonblocking read() method and a synchronized and blocking write() method.

The writer and reader parameters, if non-null, are checked to insure that they are compatible with the MemoryArea specified by memory (if non-null.) If memory is null and both Runnables are non-null, the constructor will select the nearest common scoped parent memory area, or if there is no such scope it will use immortal memory. If all three parameters are null, the queue will be allocated in immortal memory.

reader and writer are not necessarily the only threads or schedulable objects that will access the queue; moreover, there is no check that they actually access the queue at all.

Note: that the wait free queue's internal queue is allocated in memory, but the memory area of the wait free queue instance itself is determined by the current allocation context.

Parameters:
writer - An instance of Runnable or null.
reader - An instance of Runnable or null.
maximum - The maximum number of elements in the queue.
memory - The MemoryArea in which this object and internal elements are allocated.
Throws:
java.lang.IllegalArgumentException - Thrown if an argument holds an invalid value. The writer argument must be null, a reference to a Thread, or a reference to a schedulable object (a RealtimeThread, or an AsyncEventHandler.) The reader argument must be null, a reference to a Thread, or a reference to a schedulable object. The maximum argument must be greater than zero.
MemoryScopeException - Thrown if either reader or writer is non-null and the memory argument is not compatible with reader and writer with respect to the assignment and access rules for memory areas.
InnaccessibleAreaException - Thrown if memory is a scoped memory that is not on the caller's scope stack.

WaitFreeReadQueue

public WaitFreeReadQueue(int maximum,
                         MemoryArea memory,
                         boolean notify)
Constructs a queue containing up to maximum elements in memory. The queue has an unsynchronized and nonblocking read() method and a synchronized and blocking write() method.

Note: that the wait free queue's internal queue is allocated in memory, but the memory area of the wait free queue instance itself is determined by the current allocation context.

Parameters:
maximum - The maximum number of elements in the queue.
memory - The MemoryArea in which this object and internal elements are allocated.
notify - A flag that establishes whether a reader is notified when the queue becomes non-empty.
Throws:
java.lang.IllegalArgumentException - Thrown if the maximum argument is less than or equal to zero, or memory is null.
Since:
1.0.1

WaitFreeReadQueue

public WaitFreeReadQueue(int maximum,
                         boolean notify)
Constructs a queue containing up to maximum elements in immortal memory. The queue has an unsynchronized and nonblocking read() method and a synchronized and blocking write() method.

Parameters:
maximum - The maximum number of elements in the queue.
notify - A flag that establishes whether a reader is notified when the queue becomes non-empty.
Throws:
java.lang.IllegalArgumentException - Thrown if the maximum argument is less than or equal to zero.
Since:
1.0.1
Method Detail

clear

public void clear()
Sets this to empty.

Note: This method needs to be used with care. Invoking clear concurrently with read or write can lead to unexpected results.


isEmpty

public boolean isEmpty()
Queries the queue to determine if this is empty.

Note: This method needs to be used with care since the state of the queue may change while the method is in progress or after it has returned.

Returns:
true if this is empty; false if this is not empty.

isFull

public boolean isFull()
Queries the system to determine if this is full.

Note: This method needs to be used with care since the state of the queue may change while the method is in progress or after it has returned.

Returns:
true if this is full; false if this is not full.

read

public java.lang.Object read()
Reads the least recently inserted element from the queue and returns it as the result, unless the queue is empty. If the queue is empty, null is returned.

Returns:
The java.lang.Object read, or else null if this is empty.

size

public int size()
Queries the queue to determine the number of elements in this.

Note: This method needs to be used with care since the state of the queue may change while the method is in progress or after it has returned.

Returns:
The number of positions in this occupied by elements that have been written but not yet read.

waitForData

public void waitForData()
                 throws java.lang.InterruptedException
If this is empty block until a writer inserts an element.

Note: If there is a single reader and no asynchronous invocation of clear, then it is safe to invoke read after waitForData and know that read will find the queue non-empty.

Implementation note: To avoid reader and writer synchronizing on the same object, the reader should not be notified directly by a writer. (This is the issue that the non-wait queue classes are intended to solve).

Throws:
java.lang.UnsupportedOperationException - Thrown if this has not been constructed with notify set to true.
java.lang.InterruptedException - Thrown if the thread is interrupted by interrupt() or AsynchronouslyInterruptedException.fire() during the time between calling this method and returning from it.
Since:
1.0.1 InterruptedException was added to the throws clause.

write

public void write(java.lang.Object object)
           throws java.lang.InterruptedException
A synchronized and blocking write. This call blocks on queue full and will wait until there is space in the queue.

Parameters:
object - The java.lang.Object that is placed in the queue.
Throws:
java.lang.InterruptedException - Thrown if the thread is interrupted by interrupt() or AsynchronouslyInterruptedException.fire() during the time between calling this method and returning from it.
MemoryScopeException - Thrown if a memory access error or illegal assignment error would occur while storing object in the queue.
Since:
1.0.1 The return type is changed to void since it always returned true, and InterruptedException was added to the throws clause.
Mackinac comments:
IllegalArgumentException thrown if object is null. The read method is non-blocking and returns null when the queue is empty.