Class ConcurrentBag<T extends ConcurrentBagEntry>

  • 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
      void add​(T bagEntry)
      Add a new object to the bag for others to borrow.
      T borrow​(long timeout, TimeUnit timeUnit)
      The method will borrow a BagEntry from the bag, blocking for the specified timeout if none are available.
      void close()
      Close the bag to further adds.
      void dumpState()  
      int getCount​(int state)
      Get a count of the number of items in the specified state at the time of this call.
      int[] getStateCounts()  
      int getWaitingThreadCount()
      Get the number of threads pending (waiting) for an item from the bag to become available.
      boolean remove​(T bagEntry)
      Remove a value from the bag.
      void requite​(T bagEntry)
      This method will return a borrowed object to the bag.
      boolean reserve​(T bagEntry)
      The method is used to make an item in the bag "unavailable" for borrowing.
      int size()
      Get the total number of items in the bag.
      void unreserve​(T bagEntry)
      This method is used to make an item reserved via reserve(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.
    • Constructor Detail

      • ConcurrentBag

        public ConcurrentBag()
        Construct a ConcurrentBag with the specified listener.
    • 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 unit
        timeUnit - a TimeUnit determining 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 null
        IllegalStateException - 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 by borrow(long, TimeUnit) or reserve(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:
        close in interface AutoCloseable
      • 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. Call reserve(T) on items in list before performing any action on them.
        Parameters:
        state - one of the ConcurrentBagEntry states
        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. Call reserve(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 the values(int) method. Items that are reserved can be removed from the bag via remove(T) without the need to unreserve them. Items that are not removed from the bag can be make available for borrowing again by calling the unreserve(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 via reserve(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()