Class Threaded<E>

java.lang.Object
one.microstream.concurrency.Threaded<E>
All Implemented Interfaces:
ConsolidatableCollection, OptimizableCollection, Sized, Referencing<E>
Direct Known Subclasses:
ThreadedInstantiating

public class Threaded<E>
extends Object
implements ConsolidatableCollection, OptimizableCollection, Referencing<E>
Thread local context class that maintains Thread-to-instance associations.

This means that instances of this class can be used to make instances of type E effectively thread local and thus instances of this class can be seen as a kind of "wrapper" for fields that makes them thread local as if it would be a language feature.

Example:


public class SomeClass
{
    private final Threaded<StringBuilder> sb = new Threaded<StringBuilder>();

    // ...

    private void initialize() // initialize for current thread
    {
        sb.set(new StringBuilder());
    }

    private void doStuff()
    {
        sb.get().append("stuff"); // uses each thread's own exclusive StringBuilder instance
    }

    public String toString()
    {
        return sb.get().toString(); // the current thread's constructed String
    }

}

The striking feature about this class is that only those procedures are synchronized that modify the internal storage commonly used for all threads, while procedures that don't modify shared structures (like get() or set(E) to modify an existing association) are explicitly NOT synchronized, yet still thread-safe due to exploiting special characteristics of Thread identities that avoid concurrency issues (simple example: by using the Thread instance itself as the hash key for associations, each thread can only find its own association and never reach the others).
This makes this class dramatically more runtime efficient than the (with all due respect, "clumsy") ThreadLocal implementation (that even unnecessarily bloats Thread instances themselves, but that can't be fixed here).

See ThreadedInstantiating for an extended implementation that automatically utilizes an Instantiator instance to create to be associated instances for threads that dont' have an association, yet.

  • Constructor Summary

    Constructors 
    Constructor Description
    Threaded()
    Instantiates a new empty Threaded instance with default (quite small) storage size.
    Threaded​(int initialCapacity)
    Instantiates a new empty Threaded instance with a storage size of at least the passed value.
  • Method Summary

    Modifier and Type Method Description
    protected void addForCurrentThread​(E element)
    Adds a new entry associating the passed instance of type E with the current Thread.
    long consolidate()
    Consolidates the internal storage of this Threaded instance (i.e.
    boolean containsSearched​(Predicate<? super E> predicate)  
    E get()
    Returns the instance of type E associated with the current Thread.
    Consumer<E> getCleanUpOperation()  
    boolean isEmpty()
    Returns true if this Threaded instance contains no entries for associating instances of type E, otherwise false.
    protected E lookupMissFallbackElement()
    This method is called if the lookup in get() didn't find an entry for the current Thread to provide a fallback reference to be returned by get().
    static <E> Threaded<E> New()  
    static <E> Threaded<E> New​(E currentThreadsElement)
    Creates a new Threaded instance and associates the passed instance of type E with the current Thread.
    long optimize()
    Optimizes the interal storage of this Threaded instance by removing all entries that no longer reference an existing thread, determining the new required storage size afterwards and rebuilding the storage if necessary.
    E remove()
    Removes the association for the current Thread, releasing and returning the reference to the instance of type E so far associated with with it.
    E set​(E element)
    Associates the passed instance of type E with the current Thread and returns the instance of type E that has been associated with the current Thread so far, or null if nothign has been associated with the current Thread, yet.
    Threaded<E> setCleanUpOperation​(Consumer<E> cleanUpOperation)  
    long size()
    The amount of associations contained in this Threaded instance.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • Threaded

      public Threaded()
      Instantiates a new empty Threaded instance with default (quite small) storage size.
      See Also:
      Threaded(int)
    • Threaded

      public Threaded​(int initialCapacity)
      Instantiates a new empty Threaded instance with a storage size of at least the passed value.

      The created instance is guaranteed to be able to store an amount of associations equal to the passed value before a storage rebuild occurs.

      Note that the internal storage size can drop below the passed value (to the same size used by Threaded()) if at some point the optimizing algorithm detects that a smaller storage size will suffice. This is guaranteed not to happen before the storage size allocated depending on the passed value had to be increased at least once (i.e. the initial capacity remains guaranteed for the initial life time of the created instance).

      Parameters:
      initialCapacity - the minimal storage size the Threaded instance gets allocated with.
      See Also:
      Threaded(), optimize()
  • Method Details

    • New

      public static final <E> Threaded<E> New()
    • New

      public static final <E> Threaded<E> New​(E currentThreadsElement)
      Creates a new Threaded instance and associates the passed instance of type E with the current Thread.
      Type Parameters:
      E - the element type of the instances handled by the to be created Threaded instance.
      Parameters:
      currentThreadsElement - the instance of type E to be associated with the current Thread.
      Returns:
      a newly created Threaded instance associating the passed element instance with the current Thread.
      See Also:
      Threaded(), ThreadedInstantiating.threaded(Instantiator)
    • getCleanUpOperation

      public Consumer<E> getCleanUpOperation()
    • setCleanUpOperation

      public Threaded<E> setCleanUpOperation​(Consumer<E> cleanUpOperation)
    • get

      public E get()
      Returns the instance of type E associated with the current Thread.

      If no instance is associated for the current Thread yet, a fallback reference of type E is returned, which is null in the default implementation, indicating that no associated instance could have been found.

      Specified by:
      get in interface Referencing<E>
      Returns:
      the instance of type E associated with the current Thread.
      See Also:
      set(E), remove()
    • set

      public E set​(E element)
      Associates the passed instance of type E with the current Thread and returns the instance of type E that has been associated with the current Thread so far, or null if nothign has been associated with the current Thread, yet.

      Note that repeated calls to this method for the same Thread will be significantly faster and wont block other threads as the existance of a thread-exclusive entry to be updated with the passed element is already guaranteed by the first call.

      Parameters:
      element - the instance of type E that shall be associated with the current Thread.
      Returns:
      the instance of type E that has been associated with the current Thread so far.
      See Also:
      get(), remove()
    • remove

      public E remove()
      Removes the association for the current Thread, releasing and returning the reference to the instance of type E so far associated with with it.

      Note that repeated calls to this method for the same Thread will be significantly faster and wont block other threads as the removal of the thread-exclusive entry is already guaranteed by the first call.

      Returns:
      the instance of type E so far associated with the current Thread.
      See Also:
      get(), set(E)
    • lookupMissFallbackElement

      protected E lookupMissFallbackElement()
      This method is called if the lookup in get() didn't find an entry for the current Thread to provide a fallback reference to be returned by get().

      By default, this method simply returns null, indicating that no associated instance could have been found.
      Subclasses can override this method to provide an actual fallback instance in case of a lookup miss.
      In combination with #addForCurrentThread(E), this method can be used to automatically associate the fallback instance with the current Thread in case it has no instance associated, yet.

      See ThreadedInstantiating for an example using an Instantiator to automatically create a missing instance by using a wrapped Instantiator instance.

      Returns:
      null.
      See Also:
      get()
    • addForCurrentThread

      protected void addForCurrentThread​(E element)
      Adds a new entry associating the passed instance of type E with the current Thread.

      This method is only to be called from a context where it has been already determined that this Threaded instance does not contain a corresponding entry, yet. See get() and set(Object) for examples.

      Parameters:
      element - the instance of type E to be associated with the current Thread in a new entry.
    • optimize

      public long optimize()
      Optimizes the interal storage of this Threaded instance by removing all entries that no longer reference an existing thread, determining the new required storage size afterwards and rebuilding the storage if necessary.

      Note that determining dead entries takes a certain amount of time, so repeated calls of this method each cost a certain amount of time, also much lower than an actual rebuild takes.

      The method set(Object) automatically causes optimisation if it becomes necessary to enlarge the internal storage. This also leads to automatically shrinking the internal storage if possible. That is if the analysis of internal storage space prior to enlarging it discards enough empty entries so that a smaller internal storage suffices.
      As a consequence, this method has hardly to be called at all. The only situation where explicit calls of this method are needed is if the Threaded instance maintains many (potentially obsolote) associations but no further set(Object) procedure is performed that would eventually shrink the storage automatically.

      This method returns the amount of associations (threads) that can be added before the internal storage has to be optimized again, as defined by OptimizableCollection.optimize().

      Specified by:
      optimize in interface OptimizableCollection
      Returns:
      amount of associations (threads) that can be added before the internal storage has to be optimized again.
      See Also:
      consolidate()
    • consolidate

      public long consolidate()
      Consolidates the internal storage of this Threaded instance (i.e. removes all entries that no longer reference an existing Thread) by optimizing the internal storage.

      See optimize() for further details.

      In contrast to optimize(), this method returns the number of empty entries discarded in the process.

      Specified by:
      consolidate in interface ConsolidatableCollection
      Returns:
      the number of empty entries that have been removed in the process.
      See Also:
      optimize()
    • isEmpty

      public boolean isEmpty()
      Returns true if this Threaded instance contains no entries for associating instances of type E, otherwise false.

      Note that empty entries (entries that no longer reference an existing thread) do still count as contained entries. As a consequence, in order to determine if Threaded instance is actually empty regarding still valid entries, consolidate() should be called immediately prior to calling this method.

      Specified by:
      isEmpty in interface Sized
      Returns:
      true if this Threaded instance contains no associations.
      See Also:
      size(), consolidate()
    • size

      public long size()
      The amount of associations contained in this Threaded instance.

      Note that empty entries (entries that no longer reference an existing thread) do still count as contained entries. As a consequence, in order to determine the actual amount of valid entries, consolidate() should be called immediately prior to calling this method.

      Specified by:
      size in interface Sized
      Returns:
      the amount of associations contained in this Threaded instance.
      See Also:
      isEmpty(), consolidate()
    • containsSearched

      public boolean containsSearched​(Predicate<? super E> predicate)