Class 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
-
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 currentThread
.long
consolidate()
Consolidates the internal storage of thisThreaded
instance (i.e.boolean
containsSearched(Predicate<? super E> predicate)
E
get()
Returns the instance of type E associated with the currentThread
.Consumer<E>
getCleanUpOperation()
boolean
isEmpty()
Returnstrue
if thisThreaded
instance contains no entries for associating instances of type E, otherwisefalse
.protected E
lookupMissFallbackElement()
static <E> Threaded<E>
New()
static <E> Threaded<E>
New(E currentThreadsElement)
long
optimize()
Optimizes the interal storage of thisThreaded
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 currentThread
, releasing and returning the reference to the instance of type E so far associated with with it.E
set(E element)
Threaded<E>
setCleanUpOperation(Consumer<E> cleanUpOperation)
long
size()
The amount of associations contained in thisThreaded
instance.
-
Constructor Details
-
Threaded
public Threaded()Instantiates a new emptyThreaded
instance with default (quite small) storage size.- See Also:
Threaded(int)
-
Threaded
public Threaded(int initialCapacity)Instantiates a new emptyThreaded
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 theThreaded
instance gets allocated with.- See Also:
Threaded()
,optimize()
-
-
Method Details
-
New
-
New
Creates a newThreaded
instance and associates the passed instance of type E with the currentThread
.- Type Parameters:
E
- the element type of the instances handled by the to be createdThreaded
instance.- Parameters:
currentThreadsElement
- the instance of type E to be associated with the currentThread
.- Returns:
- a newly created
Threaded
instance associating the passed element instance with the currentThread
. - See Also:
Threaded()
,ThreadedInstantiating.threaded(Instantiator)
-
getCleanUpOperation
-
setCleanUpOperation
-
get
-
set
Associates the passed instance of type E with the currentThread
and returns the instance of type E that has been associated with the currentThread
so far, ornull
if nothign has been associated with the currentThread
, 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. -
remove
Removes the association for the currentThread
, 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. -
lookupMissFallbackElement
This method is called if the lookup inget()
didn't find an entry for the currentThread
to provide a fallback reference to be returned byget()
.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 withaddForCurrentThread(Object)
, this method can be used to automatically associate the fallback instance with the currentThread
in case it has no instance associated, yet.See
ThreadedInstantiating
for an example using anInstantiator
to automatically create a missing instance by using a wrappedInstantiator
instance.- Returns:
null
.- See Also:
get()
-
addForCurrentThread
Adds a new entry associating the passed instance of type E with the currentThread
.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. Seeget()
andset(Object)
for examples.- Parameters:
element
- the instance of type E to be associated with the currentThread
in a new entry.
-
optimize
public long optimize()Optimizes the interal storage of thisThreaded
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 theThreaded
instance maintains many (potentially obsolote) associations but no furtherset(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 interfaceOptimizableCollection
- 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 thisThreaded
instance (i.e. removes all entries that no longer reference an existingThread
) 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 interfaceConsolidatableCollection
- Returns:
- the number of empty entries that have been removed in the process.
- See Also:
optimize()
-
isEmpty
public boolean isEmpty()Returnstrue
if thisThreaded
instance contains no entries for associating instances of type E, otherwisefalse
.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 interfaceSized
- Returns:
true
if thisThreaded
instance contains no associations.- See Also:
size()
,consolidate()
-
size
public long size()The amount of associations contained in thisThreaded
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 interfaceSized
- Returns:
- the amount of associations contained in this
Threaded
instance. - See Also:
isEmpty()
,consolidate()
-
containsSearched
-