Class ConcurrentBag<T extends ConcurrentBagEntry>
- java.lang.Object
-
- org.xipki.pkcs11.wrapper.concurrent.ConcurrentBag<T>
-
- Type Parameters:
T- the templated type to store in the bag
- All Implemented Interfaces:
AutoCloseable
public class ConcurrentBag<T extends ConcurrentBagEntry> extends Object implements AutoCloseable
This is a specialized concurrent bag that achieves superior performance to LinkedBlockingQueue and LinkedTransferQueue for the purposes of a connection pool. It uses ThreadLocal storage when possible to avoid locks, but resorts to scanning a common collection if there are no available items in the ThreadLocal list. Not-in-use items in the ThreadLocal lists can be "stolen" when the borrowing thread has none of its own. It is a "lock-less" implementation using a specialized AbstractQueuedLongSynchronizer to manage cross-thread signaling. Note that items that are "borrowed" from the bag are not actually removed from any collection, so garbage collection will not occur even if the reference is abandoned. Thus care must be taken to "requite" borrowed objects otherwise a memory leak will result. Only the "remove" method can completely remove an object from the bag.- Author:
- Brett Wooldridge
-
-
Constructor Summary
Constructors Constructor Description ConcurrentBag()Construct a ConcurrentBag with the specified listener.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidadd(T bagEntry)Add a new object to the bag for others to borrow.Tborrow(long timeout, TimeUnit timeUnit)The method will borrow a BagEntry from the bag, blocking for the specified timeout if none are available.voidclose()Close the bag to further adds.voiddumpState()intgetCount(int state)Get a count of the number of items in the specified state at the time of this call.int[]getStateCounts()intgetWaitingThreadCount()Get the number of threads pending (waiting) for an item from the bag to become available.booleanremove(T bagEntry)Remove a value from the bag.voidrequite(T bagEntry)This method will return a borrowed object to the bag.booleanreserve(T bagEntry)The method is used to make an item in the bag "unavailable" for borrowing.intsize()Get the total number of items in the bag.voidunreserve(T bagEntry)This method is used to make an item reserved viareserve(T)available again for borrowing.List<T>values()This method provides a "snapshot" in time of the bag items.List<T>values(int state)This method provides a "snapshot" in time of the BagEntry items in the bag in the specified state.
-
-
-
Method Detail
-
borrow
public T borrow(long timeout, TimeUnit timeUnit) throws InterruptedException
The method will borrow a BagEntry from the bag, blocking for the specified timeout if none are available.- Parameters:
timeout- how long to wait before giving up, in units of unittimeUnit- aTimeUnitdetermining how to interpret the timeout parameter- Returns:
- a borrowed instance from the bag or null if a timeout occurs
- Throws:
InterruptedException- if interrupted while waiting
-
requite
public void requite(T bagEntry)
This method will return a borrowed object to the bag. Objects that are borrowed from the bag but never "requited" will result in a memory leak.- Parameters:
bagEntry- the value to return to the bag- Throws:
NullPointerException- if value is nullIllegalStateException- if the bagEntry was not borrowed from the bag
-
add
public void add(T bagEntry)
Add a new object to the bag for others to borrow.- Parameters:
bagEntry- an object to add to the bag
-
remove
public boolean remove(T bagEntry)
Remove a value from the bag. This method should only be called with objects obtained byborrow(long, TimeUnit)orreserve(T)- Parameters:
bagEntry- the value to remove- Returns:
- true if the entry was removed, false otherwise
- Throws:
IllegalStateException- if an attempt is made to remove an object from the bag that was not borrowed or reserved first
-
close
public void close()
Close the bag to further adds.- Specified by:
closein interfaceAutoCloseable
-
values
public List<T> values(int state)
This method provides a "snapshot" in time of the BagEntry items in the bag in the specified state. It does not "lock" or reserve items in any way. Callreserve(T)on items in list before performing any action on them.- Parameters:
state- one of theConcurrentBagEntrystates- Returns:
- a possibly empty list of objects having the state specified
-
values
public List<T> values()
This method provides a "snapshot" in time of the bag items. It does not "lock" or reserve items in any way. Callreserve(T)on items in the list, or understand the concurrency implications of modifying items, before performing any action on them.- Returns:
- a possibly empty list of (all) bag items
-
reserve
public boolean reserve(T bagEntry)
The method is used to make an item in the bag "unavailable" for borrowing. It is primarily used when wanting to operate on items returned by thevalues(int)method. Items that are reserved can be removed from the bag viaremove(T)without the need to unreserve them. Items that are not removed from the bag can be make available for borrowing again by calling theunreserve(T)method.- Parameters:
bagEntry- the item to reserve- Returns:
- true if the item was able to be reserved, false otherwise
-
unreserve
public void unreserve(T bagEntry)
This method is used to make an item reserved viareserve(T)available again for borrowing.- Parameters:
bagEntry- the item to unreserve
-
getWaitingThreadCount
public int getWaitingThreadCount()
Get the number of threads pending (waiting) for an item from the bag to become available.- Returns:
- the number of threads waiting for items from the bag
-
getCount
public int getCount(int state)
Get a count of the number of items in the specified state at the time of this call.- Parameters:
state- the state of the items to count- Returns:
- a count of how many items in the bag are in the specified state
-
getStateCounts
public int[] getStateCounts()
-
size
public int size()
Get the total number of items in the bag.- Returns:
- the number of items in the bag
-
dumpState
public void dumpState()
-
-