ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java (file contents):
Revision 1.93 by jsr166, Sun Jul 17 13:05:58 2011 UTC vs.
Revision 1.94 by jsr166, Mon Jul 18 20:08:18 2011 UTC

# Line 719 | Line 719 | public class ArrayBlockingQueue<E> exten
719      }
720  
721      /**
722 <     * Shared data between iterators and their queue.  Allows queue
722 >     * Shared data between iterators and their queue, allowing queue
723       * modifications to update iterators when elements are removed.
724       *
725 <     * We track all active iterators in a linked list of weak references
726 <     * to Itr, so that queue operations can update the iterators.  The
727 <     * list is cleaned up using 3 different mechanisms:
725 >     * This adds a lot of complexity for the sake of correctly
726 >     * handling some uncommon operations, but the combination of
727 >     * circular-arrays and supporting interior removes (i.e., those
728 >     * not at head) would cause iterators to sometimes lose their
729 >     * places and/or (re)report elements they shouldn't.  To avoid
730 >     * this, when a queue has one or more iterators, it keeps iterator
731 >     * state consistent by:
732 >     *
733 >     * (1) keeping track of the number of "cycles", that is, the
734 >     *     number of times takeIndex has wrapped around to 0.
735 >     * (2) notifying all iterators via the callback removedAt whenever
736 >     *     an interior element is removed (and thus other elements may
737 >     *     be shifted).
738 >     *
739 >     * These suffice to eliminate iterator inconsistencies, but
740 >     * unfortunately add the secondary responsibility of maintaining
741 >     * the list of iterators.  We track all active iterators in a
742 >     * simple linked list (accessed only when the queue's lock is
743 >     * held) of weak references to Itr.  The list is cleaned up using
744 >     * 3 different mechanisms:
745       *
746       * (1) Whenever a new iterator is created, do some O(1) checking for
747       *     stale list elements.
# Line 735 | Line 752 | public class ArrayBlockingQueue<E> exten
752       * (3) Whenever the queue becomes empty, all iterators are notified
753       *     and this entire data structure is discarded.
754       *
755 <     * Whenever a list element is examined, it is expunged if either the
756 <     * GC has determined that the iterator is discarded, or if the
757 <     * iterator reports that it is "detached" (does not need any further
758 <     * state updates).
759 <     *
760 <     * This achieves our goals of a high-reliability iterator that adds
761 <     * very little overhead if users don't create iterators.  The most
762 <     * overhead is seen if takeIndex never advances, iterators are
763 <     * discarded before they are exhausted, and all removals are
764 <     * interior removes, in which case all stale iterators are
765 <     * discovered by the GC.  But even in this case we don't increase
766 <     * the amortized complexity.
755 >     * So in addition to the removedAt callback that is necessary for
756 >     * correctness, iterators have the shutdown and takeIndexWrapped
757 >     * callbacks that help remove stale iterators from the list.
758 >     *
759 >     * Whenever a list element is examined, it is expunged if either
760 >     * the GC has determined that the iterator is discarded, or if the
761 >     * iterator reports that it is "detached" (does not need any
762 >     * further state updates).  Overhead is maximal when takeIndex
763 >     * never advances, iterators are discarded before they are
764 >     * exhausted, and all removals are interior removes, in which case
765 >     * all stale iterators are discovered by the GC.  But even in this
766 >     * case we don't increase the amortized complexity.
767 >     *
768 >     * Care must be taken to keep list sweeping methods from
769 >     * reentrantly invoking another such method, causing subtle
770 >     * corruption bugs.
771       */
772      class Itrs {
773  
# Line 781 | Line 802 | public class ArrayBlockingQueue<E> exten
802          /**
803           * Sweeps itrs, looking for and expunging stale iterators.
804           * If at least one was found, tries harder to find more.
805 +         * Called only from iterating thread.
806           *
807           * @param tryHarder whether to start in try-harder mode, because
808           * there is known to be at least one iterator to collect

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines