com.atlassian.util.concurrent
Class BlockingReference<V>

java.lang.Object
  extended by com.atlassian.util.concurrent.BlockingReference<V>
Type Parameters:
V - the value type

@ThreadSafe
public class BlockingReference<V>
extends java.lang.Object

A Reference with queue semantics where the current reference may be retrieved or taken instead, and if there is no current element then it will be block until the reference becomes available. This is somewhat analogous to a single element BlockingQueue.

Note: this class does not support null elements being set(Object) and will throw an exception. If the internal reference is null, then calls to take() or take(long, TimeUnit) will block.

This class is most suited to SRSW or MRSW usage. Multiple writers will overwrite each other's elements and the chosen value will be arbitrary in the absence of any external consensus. If multiple readers are waiting to take() a value, one reader will be arbitrarily chosen (similar to Condition.signal()). Multiple readers can however get() the current value if it is not null, but they may see the current value more than once. If multiple readers attempt to get() a value from the SRSW reference and it is not yet present then only one waiting thread may be notified, please use the MRSW version for this case.

This implementation has been optimized for SRSW performance with set(Object)/take() pairs.

Prometheus contains a similar construct called an AwaitableReference. This class is more explicit in that it handles take/get separately.

Author:
Jed Wesley-Smith
See Also:
BlockingQueue

Constructor Summary
BlockingReference()
          Deprecated. use newSRSW() instead.
BlockingReference(V value)
          Deprecated. use newSRSW() instead.
 
Method Summary
 void clear()
          Clear the current reference.
 V get()
          Gets the current element if it is not null, if it is null then this method blocks and waits until it is not null.
 V get(long time, java.util.concurrent.TimeUnit unit)
          Gets the current element if it is not null, if it is null then this method blocks and waits until it is not null.
 boolean isEmpty()
          Whether or not the current value is null or not.
static
<V> BlockingReference<V>
newMRSW()
          Create a BlockingReference best suited to multi-reader/single-writer situations.
static
<V> BlockingReference<V>
newMRSW(V initialValue)
          Create a BlockingReference best suited to multi-reader/single-writer situations.
static
<V> BlockingReference<V>
newSRSW()
          Create a BlockingReference best suited to single-reader/single-writer situations.
static
<V> BlockingReference<V>
newSRSW(V initialValue)
          Create a BlockingReference best suited to single-reader/single-writer situations.
 V peek()
          Return the current value whether is null or not.
 void set(V value)
          Set the value of this reference.
 V take()
          Takes the current element if it is not null and replaces it with null.
 V take(long time, java.util.concurrent.TimeUnit unit)
          Takes the current element if it is not null and replaces it with null.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

BlockingReference

@Deprecated
public BlockingReference()
Deprecated. use newSRSW() instead.

Creates a new SRSW BlockingReference.


BlockingReference

@Deprecated
public BlockingReference(@NotNull
                                    V value)
Deprecated. use newSRSW() instead.

Creates a new SRSW BlockingReference.

Method Detail

newSRSW

public static <V> BlockingReference<V> newSRSW()
Create a BlockingReference best suited to single-reader/single-writer situations. In a MRSW case this instance may get missed signals if multiple reader threads are all waiting on the value.


newSRSW

public static <V> BlockingReference<V> newSRSW(V initialValue)
Create a BlockingReference best suited to single-reader/single-writer situations. In a MRSW case this instance may get missed signals if multiple reader threads are all waiting on the value.

Parameters:
initialValue - the initial value

newMRSW

public static <V> BlockingReference<V> newMRSW()
Create a BlockingReference best suited to multi-reader/single-writer situations. In a SRSW case this instance may not perform quite as well.


newMRSW

public static <V> BlockingReference<V> newMRSW(V initialValue)
Create a BlockingReference best suited to multi-reader/single-writer situations. In a SRSW case this instance may not perform quite as well.

Parameters:
initialValue - the initial value

take

@NotNull
public V take()
       throws java.lang.InterruptedException
Takes the current element if it is not null and replaces it with null. If the current element is null then wait until it becomes non-null.

If the current thread:

then InterruptedException is thrown and the current thread's interrupted status is cleared.

Returns:
the current element
Throws:
java.lang.InterruptedException - if the current thread is interrupted while waiting

take

@NotNull
public V take(long time,
                      java.util.concurrent.TimeUnit unit)
       throws java.util.concurrent.TimeoutException,
              java.lang.InterruptedException
Takes the current element if it is not null and replaces it with null. If the current element is null then wait until it becomes non-null. The method will throw a TimeoutException if the timeout is reached before an element becomes available.

If the current thread:

then InterruptedException is thrown and the current thread's interrupted status is cleared.

Parameters:
time - the maximum time to wait
unit - the time unit of the timeout argument
Returns:
the current element
Throws:
java.lang.InterruptedException - if the current thread is interrupted while waiting
java.util.concurrent.TimeoutException - if the timeout is reached without another thread having called set(Object).

get

@NotNull
public V get()
      throws java.lang.InterruptedException
Gets the current element if it is not null, if it is null then this method blocks and waits until it is not null. Unlike take() it does not reset the current element to null.

If the current thread:

then InterruptedException is thrown and the current thread's interrupted status is cleared.

Returns:
the current element
Throws:
java.lang.InterruptedException - if the current thread is interrupted while waiting

get

@NotNull
public V get(long time,
                     @NotNull
                     java.util.concurrent.TimeUnit unit)
      throws java.util.concurrent.TimeoutException,
             java.lang.InterruptedException
Gets the current element if it is not null, if it is null then this method blocks and waits until it is not null. Unlike take() it does not reset the current element to null.

If the current thread:

then InterruptedException is thrown and the current thread's interrupted status is cleared.

Returns:
the current element
Throws:
java.util.concurrent.TimeoutException - if the timeout is reached without another thread having called set(Object).
java.lang.InterruptedException - if the current thread is interrupted while waiting

set

public void set(@NotNull
                V value)
Set the value of this reference. This method is lock-free. A thread waiting in take() or take(long, TimeUnit) will be released and given this value.

Parameters:
value - the new value.

isEmpty

public boolean isEmpty()
Whether or not the current value is null or not. If this is true and the next call to take() or take(long, TimeUnit) will not block.

Returns:
true if the current reference is null.

peek

@Nullable
public V peek()
Return the current value whether is null or not. If this is true and the next call to take() or take(long, TimeUnit) will not block.

Returns:
the current reference or null if there is none.

clear

public void clear()
Clear the current reference.



Copyright © 2009 Atlassian Pty Ltd. All Rights Reserved.