public class Pool<E> extends WeakInterningHashSet<E>
weak interning hash set
particularly well-suited for implementing a pool of instances.
All access is thread safe, guarded with a shared read
lock and an exclusive getWriteLock()
lock
to support multiple simultaneous readers while ensuring that writes are properly serial.
The locks are held for the minimal period to allow maximal concurrency.
Removals, i.e., remove
, removeAll
, clear
, and retainAll
, are not supported.Modifier and Type | Class and Description |
---|---|
protected static class |
Pool.AccessUnit<E>
An access unit is used during access to the pool.
|
protected static class |
Pool.ExternalRehasher<E> |
protected static class |
Pool.ObjectAccessUnit<E> |
protected static class |
Pool.PoolEntry<E> |
WeakInterningHashSet.Entry<E>, WeakInterningHashSet.SelfCleaningEntry<E>
Modifier and Type | Field and Description |
---|---|
protected int |
accessCount
Record the number of accesses so that the
cleanup() can be called occasionally. |
protected int |
cleanupPeriod
The number of
access between each attempt to clean up garbage collected entries. |
protected Pool.AccessUnit.Queue<E> |
primaryAccessUnits |
protected java.util.concurrent.locks.Lock |
readLock
To support maximum concurrency, a pair of read and write locks is maintained; this is the
read lock . |
protected java.util.concurrent.locks.ReentrantReadWriteLock |
readWriteLock |
protected java.util.concurrent.locks.Lock |
writeLock
To support maximum concurrency, a pair of read and write locks is maintained; this is the
write lock . |
capacityIndex, containsNull, entries, externalQueue, internalQueue, modCount, NULL_ENTRY, PRIME_CAPACITIES, size, threshold
Modifier | Constructor and Description |
---|---|
|
Pool()
Creates an instance with a capacity of 1031.
|
|
Pool(int minimumCapacity)
Creates an instance.
|
protected |
Pool(int minimumCapacity,
Pool.AccessUnit.Queue<E> primaryAccessUnits) |
protected |
Pool(int minimumCapacity,
Pool.AccessUnit.Queue<E> primaryAccessUnits,
java.lang.ref.ReferenceQueue<java.lang.Object> queue) |
Modifier and Type | Method and Description |
---|---|
protected void |
access(boolean isReadLocked,
Pool.AccessUnit<E> accessUnit)
Collect all the values with a matching hash code.
|
boolean |
add(E value)
Specialized to ensure thread safety.
|
protected E |
addEntry(boolean isExclusive,
E internalizedValue,
Pool.AccessUnit<E> accessUnit)
Adds an entry to the pool,
but first checks if the entry has been added by another thread
since the time when the pool was
accessed while without holding any locks. |
protected void |
cleanup()
Specialized to ensure that the write lock is held during cleanup.
|
void |
clear()
Throws an
UnsupportedOperationException because removal is not supported.. |
boolean |
contains(java.lang.Object value)
Specialized to ensure thread safety.
|
boolean |
containsAll(java.util.Collection<?> collection)
Specialized to ensure thread safety.
|
protected void |
doCleanup()
Calls
super. |
protected E |
doIntern(boolean isExclusive,
Pool.AccessUnit<E> accessUnit)
Returns the interned version of the value accessed by this access unit
and
frees the access unit for reuse. |
protected boolean |
ensureCapacity()
Ensures that 3/4 of current capacity is larger than the current size, i.e., that the
WeakInterningHashSet.size <= WeakInterningHashSet.threshold . |
boolean |
equals(java.lang.Object o)
Specialized to ensure thread safety.
|
E |
get(E value)
Returns either the instance already contained in the set that's equal to the given object, or
null if the object is not in the set. |
protected WeakInterningHashSet.Entry<E> |
getEntry(int hashCode)
Gets the first entry with the matching hash code.
|
java.util.concurrent.locks.Lock |
getReadLock()
Returns this pool's
read lock . |
java.util.concurrent.locks.Lock |
getWriteLock()
Returns this pool's
write lock . |
void |
grow(int minimumCapacity)
Specialized to ensure that the exclusive write lock is held during growth.
|
int |
hashCode()
Specialized to ensure thread safety.
|
E |
intern(E value)
Specialized to ensure thread safety.
|
java.util.Iterator<E> |
iterator()
Callers of the iterator must ensure that they hold the shared
read lock for the lifetime of the iterator's usage. |
protected Pool.AccessUnit.Queue<E> |
newDefaultAccessUnits() |
protected WeakInterningHashSet.Entry<E> |
newExternalEntry(E object,
int hashCode)
Creates a new entry for the given referent and the given hash code managed by the
WeakInterningHashSet.externalQueue . |
boolean |
remove(java.lang.Object object)
Throws an
UnsupportedOperationException because removal is not supported.. |
boolean |
removeAll(java.util.Collection<?> collection)
Throws an
UnsupportedOperationException because removal is not supported.. |
boolean |
retainAll(java.util.Collection<?> collection)
Throws an
UnsupportedOperationException because removal is not supported.. |
java.lang.Object[] |
toArray()
Specialized to ensure thread safety.
|
<T> T[] |
toArray(T[] a)
Specialized to ensure thread safety.
|
java.lang.String |
toString()
Specialized to ensure thread safety.
|
addEntry, asInstance, dump, equals, hashCode, index, newEntries, newEntry, newInternalEntry, nullEntry, putEntry, removeEntry, removeEntry, size
protected int accessCount
cleanup()
can be called occasionally.
It's a state modifying operation, so it must hold the exclusive write lock
during execution.protected int cleanupPeriod
access
between each attempt to clean up
garbage collected entries.
Garbage collecting entries requires the exclusive getWriteLock()
to be held, so it's best to do this infrequently.protected final java.util.concurrent.locks.ReentrantReadWriteLock readWriteLock
protected final java.util.concurrent.locks.Lock readLock
read lock
.protected final java.util.concurrent.locks.Lock writeLock
write lock
.protected final Pool.AccessUnit.Queue<E> primaryAccessUnits
public Pool()
public Pool(int minimumCapacity)
protected Pool(int minimumCapacity, Pool.AccessUnit.Queue<E> primaryAccessUnits)
protected Pool(int minimumCapacity, Pool.AccessUnit.Queue<E> primaryAccessUnits, java.lang.ref.ReferenceQueue<java.lang.Object> queue)
protected boolean ensureCapacity()
WeakInterningHashSet
WeakInterningHashSet.size
<= WeakInterningHashSet.threshold
.
If not, it reallocates
the entries to the next prime capacity
,
i.e., it approximate doubles the capacity,
and then rehashes
the set.
The return value indicates whether or note the entries where rehashed.ensureCapacity
in class WeakInterningHashSet<E>
protected WeakInterningHashSet.Entry<E> newExternalEntry(E object, int hashCode)
WeakInterningHashSet
WeakInterningHashSet.externalQueue
.newExternalEntry
in class WeakInterningHashSet<E>
protected Pool.AccessUnit.Queue<E> newDefaultAccessUnits()
public java.util.concurrent.locks.Lock getReadLock()
read lock
.
This should be used only for thread-safe iteration
in which remove
is not called.public java.util.concurrent.locks.Lock getWriteLock()
write lock
.
This should be used only for thread-safe iteration
in which remove
is called.protected WeakInterningHashSet.Entry<E> getEntry(int hashCode)
Entry#getNextEntry()
to navigate to the next entry with the same hash code.
This method does no locking so it may fail to find matches if the pool is rehashing or another thread is adding the entry.getEntry
in class WeakInterningHashSet<E>
protected final void access(boolean isReadLocked, Pool.AccessUnit<E> accessUnit)
isReadLocked
is true
it's expected that the read lock
is already locked.
In this case the access will reliably collect all the matching entries currently in the pool.
When isReadLocked
is false
, the access is done without locking and may spuriously fail to return any matches,
i.e., if the pool is currently rehashing, or another thread is currently adding the value.
Because removal
is not supported, there will never be a spurious match to a removed entry.
This also increments accessCount
and periodically
calls cleanup()
if it's not a read locked access.protected final E addEntry(boolean isExclusive, E internalizedValue, Pool.AccessUnit<E> accessUnit)
accessed
while without holding any locks.
The access unit is used to record
whether an entry was really added.
This returns either the value added, or the value that was already added by another thread.
The isExlusive
argument controls whether the write lock needs to be acquired (false
) or is already acquired (true
).protected void cleanup()
cleanup
in class WeakInterningHashSet<E>
protected void doCleanup()
super.WeakInterningHashSet.cleanup()
.
public void grow(int minimumCapacity)
grow
in class WeakInterningHashSet<E>
public boolean add(E value)
add
in interface java.util.Collection<E>
add
in interface java.util.Set<E>
add
in class WeakInterningHashSet<E>
public E intern(E value)
internalized
version is added to pool.
This implementation delegates to doIntern(boolean, AccessUnit)
.intern
in interface InterningSet<E>
intern
in class WeakInterningHashSet<E>
value
- the object to intern.protected E doIntern(boolean isExclusive, Pool.AccessUnit<E> accessUnit)
frees
the access unit for reuse.public E get(E value)
WeakInterningHashSet
null
if the object is not in the set.get
in interface InterningSet<E>
get
in class WeakInterningHashSet<E>
value
- the object to intern.null
if the object is not in the set.public boolean contains(java.lang.Object value)
read
lock.contains
in interface java.util.Collection<E>
contains
in interface java.util.Set<E>
contains
in class WeakInterningHashSet<E>
public java.util.Iterator<E> iterator()
read lock
for the lifetime of the iterator's usage.
Remove
is not supported.public boolean equals(java.lang.Object o)
public int hashCode()
public java.lang.Object[] toArray()
public <T> T[] toArray(T[] a)
public boolean containsAll(java.util.Collection<?> collection)
public boolean remove(java.lang.Object object)
UnsupportedOperationException
because removal is not supported..remove
in interface java.util.Collection<E>
remove
in interface java.util.Set<E>
remove
in class WeakInterningHashSet<E>
public boolean removeAll(java.util.Collection<?> collection)
UnsupportedOperationException
because removal is not supported..public boolean retainAll(java.util.Collection<?> collection)
UnsupportedOperationException
because removal is not supported..public void clear()
UnsupportedOperationException
because removal is not supported..clear
in interface java.util.Collection<E>
clear
in interface java.util.Set<E>
clear
in class WeakInterningHashSet<E>
public java.lang.String toString()
toString
in class java.util.AbstractCollection<E>