src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java
changeset 50229 6b29ef846c5c
parent 49792 cfdce76e0449
child 52427 3c6aa484536c
equal deleted inserted replaced
50228:45093fb73c6d 50229:6b29ef846c5c
    49 import java.util.SortedSet;
    49 import java.util.SortedSet;
    50 import java.util.Spliterator;
    50 import java.util.Spliterator;
    51 import java.util.concurrent.locks.Condition;
    51 import java.util.concurrent.locks.Condition;
    52 import java.util.concurrent.locks.ReentrantLock;
    52 import java.util.concurrent.locks.ReentrantLock;
    53 import java.util.function.Consumer;
    53 import java.util.function.Consumer;
       
    54 import java.util.function.Predicate;
    54 import jdk.internal.misc.SharedSecrets;
    55 import jdk.internal.misc.SharedSecrets;
    55 
    56 
    56 /**
    57 /**
    57  * An unbounded {@linkplain BlockingQueue blocking queue} that uses
    58  * An unbounded {@linkplain BlockingQueue blocking queue} that uses
    58  * the same ordering rules as class {@link PriorityQueue} and supplies
    59  * the same ordering rules as class {@link PriorityQueue} and supplies
   165     private transient Comparator<? super E> comparator;
   166     private transient Comparator<? super E> comparator;
   166 
   167 
   167     /**
   168     /**
   168      * Lock used for all public operations.
   169      * Lock used for all public operations.
   169      */
   170      */
   170     private final ReentrantLock lock;
   171     private final ReentrantLock lock = new ReentrantLock();
   171 
   172 
   172     /**
   173     /**
   173      * Condition for blocking when empty.
   174      * Condition for blocking when empty.
   174      */
   175      */
   175     private final Condition notEmpty;
   176     private final Condition notEmpty = lock.newCondition();
   176 
   177 
   177     /**
   178     /**
   178      * Spinlock for allocation, acquired via CAS.
   179      * Spinlock for allocation, acquired via CAS.
   179      */
   180      */
   180     private transient volatile int allocationSpinLock;
   181     private transient volatile int allocationSpinLock;
   222      */
   223      */
   223     public PriorityBlockingQueue(int initialCapacity,
   224     public PriorityBlockingQueue(int initialCapacity,
   224                                  Comparator<? super E> comparator) {
   225                                  Comparator<? super E> comparator) {
   225         if (initialCapacity < 1)
   226         if (initialCapacity < 1)
   226             throw new IllegalArgumentException();
   227             throw new IllegalArgumentException();
   227         this.lock = new ReentrantLock();
       
   228         this.notEmpty = lock.newCondition();
       
   229         this.comparator = comparator;
   228         this.comparator = comparator;
   230         this.queue = new Object[initialCapacity];
   229         this.queue = new Object[Math.max(1, initialCapacity)];
   231     }
   230     }
   232 
   231 
   233     /**
   232     /**
   234      * Creates a {@code PriorityBlockingQueue} containing the elements
   233      * Creates a {@code PriorityBlockingQueue} containing the elements
   235      * in the specified collection.  If the specified collection is a
   234      * in the specified collection.  If the specified collection is a
   245      *         queue's ordering
   244      *         queue's ordering
   246      * @throws NullPointerException if the specified collection or any
   245      * @throws NullPointerException if the specified collection or any
   247      *         of its elements are null
   246      *         of its elements are null
   248      */
   247      */
   249     public PriorityBlockingQueue(Collection<? extends E> c) {
   248     public PriorityBlockingQueue(Collection<? extends E> c) {
   250         this.lock = new ReentrantLock();
       
   251         this.notEmpty = lock.newCondition();
       
   252         boolean heapify = true; // true if not known to be in heap order
   249         boolean heapify = true; // true if not known to be in heap order
   253         boolean screen = true;  // true if must screen for nulls
   250         boolean screen = true;  // true if must screen for nulls
   254         if (c instanceof SortedSet<?>) {
   251         if (c instanceof SortedSet<?>) {
   255             SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
   252             SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
   256             this.comparator = (Comparator<? super E>) ss.comparator();
   253             this.comparator = (Comparator<? super E>) ss.comparator();
   262             this.comparator = (Comparator<? super E>) pq.comparator();
   259             this.comparator = (Comparator<? super E>) pq.comparator();
   263             screen = false;
   260             screen = false;
   264             if (pq.getClass() == PriorityBlockingQueue.class) // exact match
   261             if (pq.getClass() == PriorityBlockingQueue.class) // exact match
   265                 heapify = false;
   262                 heapify = false;
   266         }
   263         }
   267         Object[] a = c.toArray();
   264         Object[] es = c.toArray();
   268         int n = a.length;
   265         int n = es.length;
   269         // If c.toArray incorrectly doesn't return Object[], copy it.
   266         // If c.toArray incorrectly doesn't return Object[], copy it.
   270         if (a.getClass() != Object[].class)
   267         if (es.getClass() != Object[].class)
   271             a = Arrays.copyOf(a, n, Object[].class);
   268             es = Arrays.copyOf(es, n, Object[].class);
   272         if (screen && (n == 1 || this.comparator != null)) {
   269         if (screen && (n == 1 || this.comparator != null)) {
   273             for (Object elt : a)
   270             for (Object e : es)
   274                 if (elt == null)
   271                 if (e == null)
   275                     throw new NullPointerException();
   272                     throw new NullPointerException();
   276         }
   273         }
   277         this.queue = a;
   274         this.queue = ensureNonEmpty(es);
   278         this.size = n;
   275         this.size = n;
   279         if (heapify)
   276         if (heapify)
   280             heapify();
   277             heapify();
       
   278     }
       
   279 
       
   280     /** Ensures that queue[0] exists, helping peek() and poll(). */
       
   281     private static Object[] ensureNonEmpty(Object[] es) {
       
   282         return (es.length > 0) ? es : new Object[1];
   281     }
   283     }
   282 
   284 
   283     /**
   285     /**
   284      * Tries to grow array to accommodate at least one more element
   286      * Tries to grow array to accommodate at least one more element
   285      * (but normally expand by about 50%), giving up (allowing retry)
   287      * (but normally expand by about 50%), giving up (allowing retry)
   321 
   323 
   322     /**
   324     /**
   323      * Mechanics for poll().  Call only while holding lock.
   325      * Mechanics for poll().  Call only while holding lock.
   324      */
   326      */
   325     private E dequeue() {
   327     private E dequeue() {
   326         int n = size - 1;
   328         // assert lock.isHeldByCurrentThread();
   327         if (n < 0)
   329         final Object[] es;
   328             return null;
   330         final E result;
   329         else {
   331 
   330             Object[] array = queue;
   332         if ((result = (E) ((es = queue)[0])) != null) {
   331             E result = (E) array[0];
   333             final int n;
   332             E x = (E) array[n];
   334             final E x = (E) es[(n = --size)];
   333             array[n] = null;
   335             es[n] = null;
   334             Comparator<? super E> cmp = comparator;
   336             if (n > 0) {
   335             if (cmp == null)
   337                 final Comparator<? super E> cmp;
   336                 siftDownComparable(0, x, array, n);
   338                 if ((cmp = comparator) == null)
   337             else
   339                     siftDownComparable(0, x, es, n);
   338                 siftDownUsingComparator(0, x, array, n, cmp);
   340                 else
   339             size = n;
   341                     siftDownUsingComparator(0, x, es, n, cmp);
   340             return result;
   342             }
   341         }
   343         }
       
   344         return result;
   342     }
   345     }
   343 
   346 
   344     /**
   347     /**
   345      * Inserts item x at position k, maintaining heap invariant by
   348      * Inserts item x at position k, maintaining heap invariant by
   346      * promoting x up the tree until it is greater than or equal to
   349      * promoting x up the tree until it is greater than or equal to
   350      * Comparable and Comparator versions are separated into different
   353      * Comparable and Comparator versions are separated into different
   351      * methods that are otherwise identical. (Similarly for siftDown.)
   354      * methods that are otherwise identical. (Similarly for siftDown.)
   352      *
   355      *
   353      * @param k the position to fill
   356      * @param k the position to fill
   354      * @param x the item to insert
   357      * @param x the item to insert
   355      * @param array the heap array
   358      * @param es the heap array
   356      */
   359      */
   357     private static <T> void siftUpComparable(int k, T x, Object[] array) {
   360     private static <T> void siftUpComparable(int k, T x, Object[] es) {
   358         Comparable<? super T> key = (Comparable<? super T>) x;
   361         Comparable<? super T> key = (Comparable<? super T>) x;
   359         while (k > 0) {
   362         while (k > 0) {
   360             int parent = (k - 1) >>> 1;
   363             int parent = (k - 1) >>> 1;
   361             Object e = array[parent];
   364             Object e = es[parent];
   362             if (key.compareTo((T) e) >= 0)
   365             if (key.compareTo((T) e) >= 0)
   363                 break;
   366                 break;
   364             array[k] = e;
   367             es[k] = e;
   365             k = parent;
   368             k = parent;
   366         }
   369         }
   367         array[k] = key;
   370         es[k] = key;
   368     }
   371     }
   369 
   372 
   370     private static <T> void siftUpUsingComparator(int k, T x, Object[] array,
   373     private static <T> void siftUpUsingComparator(
   371                                        Comparator<? super T> cmp) {
   374         int k, T x, Object[] es, Comparator<? super T> cmp) {
   372         while (k > 0) {
   375         while (k > 0) {
   373             int parent = (k - 1) >>> 1;
   376             int parent = (k - 1) >>> 1;
   374             Object e = array[parent];
   377             Object e = es[parent];
   375             if (cmp.compare(x, (T) e) >= 0)
   378             if (cmp.compare(x, (T) e) >= 0)
   376                 break;
   379                 break;
   377             array[k] = e;
   380             es[k] = e;
   378             k = parent;
   381             k = parent;
   379         }
   382         }
   380         array[k] = x;
   383         es[k] = x;
   381     }
   384     }
   382 
   385 
   383     /**
   386     /**
   384      * Inserts item x at position k, maintaining heap invariant by
   387      * Inserts item x at position k, maintaining heap invariant by
   385      * demoting x down the tree repeatedly until it is less than or
   388      * demoting x down the tree repeatedly until it is less than or
   386      * equal to its children or is a leaf.
   389      * equal to its children or is a leaf.
   387      *
   390      *
   388      * @param k the position to fill
   391      * @param k the position to fill
   389      * @param x the item to insert
   392      * @param x the item to insert
   390      * @param array the heap array
   393      * @param es the heap array
   391      * @param n heap size
   394      * @param n heap size
   392      */
   395      */
   393     private static <T> void siftDownComparable(int k, T x, Object[] array,
   396     private static <T> void siftDownComparable(int k, T x, Object[] es, int n) {
   394                                                int n) {
   397         // assert n > 0;
   395         if (n > 0) {
   398         Comparable<? super T> key = (Comparable<? super T>)x;
   396             Comparable<? super T> key = (Comparable<? super T>)x;
   399         int half = n >>> 1;           // loop while a non-leaf
   397             int half = n >>> 1;           // loop while a non-leaf
   400         while (k < half) {
   398             while (k < half) {
   401             int child = (k << 1) + 1; // assume left child is least
   399                 int child = (k << 1) + 1; // assume left child is least
   402             Object c = es[child];
   400                 Object c = array[child];
   403             int right = child + 1;
   401                 int right = child + 1;
   404             if (right < n &&
   402                 if (right < n &&
   405                 ((Comparable<? super T>) c).compareTo((T) es[right]) > 0)
   403                     ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
   406                 c = es[child = right];
   404                     c = array[child = right];
   407             if (key.compareTo((T) c) <= 0)
   405                 if (key.compareTo((T) c) <= 0)
   408                 break;
   406                     break;
   409             es[k] = c;
   407                 array[k] = c;
   410             k = child;
   408                 k = child;
   411         }
   409             }
   412         es[k] = key;
   410             array[k] = key;
   413     }
   411         }
   414 
   412     }
   415     private static <T> void siftDownUsingComparator(
   413 
   416         int k, T x, Object[] es, int n, Comparator<? super T> cmp) {
   414     private static <T> void siftDownUsingComparator(int k, T x, Object[] array,
   417         // assert n > 0;
   415                                                     int n,
   418         int half = n >>> 1;
   416                                                     Comparator<? super T> cmp) {
   419         while (k < half) {
   417         if (n > 0) {
   420             int child = (k << 1) + 1;
   418             int half = n >>> 1;
   421             Object c = es[child];
   419             while (k < half) {
   422             int right = child + 1;
   420                 int child = (k << 1) + 1;
   423             if (right < n && cmp.compare((T) c, (T) es[right]) > 0)
   421                 Object c = array[child];
   424                 c = es[child = right];
   422                 int right = child + 1;
   425             if (cmp.compare(x, (T) c) <= 0)
   423                 if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
   426                 break;
   424                     c = array[child = right];
   427             es[k] = c;
   425                 if (cmp.compare(x, (T) c) <= 0)
   428             k = child;
   426                     break;
   429         }
   427                 array[k] = c;
   430         es[k] = x;
   428                 k = child;
       
   429             }
       
   430             array[k] = x;
       
   431         }
       
   432     }
   431     }
   433 
   432 
   434     /**
   433     /**
   435      * Establishes the heap invariant (described above) in the entire tree,
   434      * Establishes the heap invariant (described above) in the entire tree,
   436      * assuming nothing about the order of the elements prior to the call.
   435      * assuming nothing about the order of the elements prior to the call.
   437      * This classic algorithm due to Floyd (1964) is known to be O(size).
   436      * This classic algorithm due to Floyd (1964) is known to be O(size).
   438      */
   437      */
   439     private void heapify() {
   438     private void heapify() {
   440         Object[] array = queue;
   439         final Object[] es = queue;
   441         int n = size, i = (n >>> 1) - 1;
   440         int n = size, i = (n >>> 1) - 1;
   442         Comparator<? super E> cmp = comparator;
   441         final Comparator<? super E> cmp;
   443         if (cmp == null) {
   442         if ((cmp = comparator) == null)
   444             for (; i >= 0; i--)
   443             for (; i >= 0; i--)
   445                 siftDownComparable(i, (E) array[i], array, n);
   444                 siftDownComparable(i, (E) es[i], es, n);
   446         }
   445         else
   447         else {
       
   448             for (; i >= 0; i--)
   446             for (; i >= 0; i--)
   449                 siftDownUsingComparator(i, (E) array[i], array, n, cmp);
   447                 siftDownUsingComparator(i, (E) es[i], es, n, cmp);
   450         }
       
   451     }
   448     }
   452 
   449 
   453     /**
   450     /**
   454      * Inserts the specified element into this priority queue.
   451      * Inserts the specified element into this priority queue.
   455      *
   452      *
   479         if (e == null)
   476         if (e == null)
   480             throw new NullPointerException();
   477             throw new NullPointerException();
   481         final ReentrantLock lock = this.lock;
   478         final ReentrantLock lock = this.lock;
   482         lock.lock();
   479         lock.lock();
   483         int n, cap;
   480         int n, cap;
   484         Object[] array;
   481         Object[] es;
   485         while ((n = size) >= (cap = (array = queue).length))
   482         while ((n = size) >= (cap = (es = queue).length))
   486             tryGrow(array, cap);
   483             tryGrow(es, cap);
   487         try {
   484         try {
   488             Comparator<? super E> cmp = comparator;
   485             final Comparator<? super E> cmp;
   489             if (cmp == null)
   486             if ((cmp = comparator) == null)
   490                 siftUpComparable(n, e, array);
   487                 siftUpComparable(n, e, es);
   491             else
   488             else
   492                 siftUpUsingComparator(n, e, array, cmp);
   489                 siftUpUsingComparator(n, e, es, cmp);
   493             size = n + 1;
   490             size = n + 1;
   494             notEmpty.signal();
   491             notEmpty.signal();
   495         } finally {
   492         } finally {
   496             lock.unlock();
   493             lock.unlock();
   497         }
   494         }
   570 
   567 
   571     public E peek() {
   568     public E peek() {
   572         final ReentrantLock lock = this.lock;
   569         final ReentrantLock lock = this.lock;
   573         lock.lock();
   570         lock.lock();
   574         try {
   571         try {
   575             return (size == 0) ? null : (E) queue[0];
   572             return (E) queue[0];
   576         } finally {
   573         } finally {
   577             lock.unlock();
   574             lock.unlock();
   578         }
   575         }
   579     }
   576     }
   580 
   577 
   610         return Integer.MAX_VALUE;
   607         return Integer.MAX_VALUE;
   611     }
   608     }
   612 
   609 
   613     private int indexOf(Object o) {
   610     private int indexOf(Object o) {
   614         if (o != null) {
   611         if (o != null) {
   615             Object[] array = queue;
   612             final Object[] es = queue;
   616             int n = size;
   613             for (int i = 0, n = size; i < n; i++)
   617             for (int i = 0; i < n; i++)
   614                 if (o.equals(es[i]))
   618                 if (o.equals(array[i]))
       
   619                     return i;
   615                     return i;
   620         }
   616         }
   621         return -1;
   617         return -1;
   622     }
   618     }
   623 
   619 
   624     /**
   620     /**
   625      * Removes the ith element from queue.
   621      * Removes the ith element from queue.
   626      */
   622      */
   627     private void removeAt(int i) {
   623     private void removeAt(int i) {
   628         Object[] array = queue;
   624         final Object[] es = queue;
   629         int n = size - 1;
   625         final int n = size - 1;
   630         if (n == i) // removed last element
   626         if (n == i) // removed last element
   631             array[i] = null;
   627             es[i] = null;
   632         else {
   628         else {
   633             E moved = (E) array[n];
   629             E moved = (E) es[n];
   634             array[n] = null;
   630             es[n] = null;
   635             Comparator<? super E> cmp = comparator;
   631             final Comparator<? super E> cmp;
   636             if (cmp == null)
   632             if ((cmp = comparator) == null)
   637                 siftDownComparable(i, moved, array, n);
   633                 siftDownComparable(i, moved, es, n);
   638             else
   634             else
   639                 siftDownUsingComparator(i, moved, array, n, cmp);
   635                 siftDownUsingComparator(i, moved, es, n, cmp);
   640             if (array[i] == moved) {
   636             if (es[i] == moved) {
   641                 if (cmp == null)
   637                 if (cmp == null)
   642                     siftUpComparable(i, moved, array);
   638                     siftUpComparable(i, moved, es);
   643                 else
   639                 else
   644                     siftUpUsingComparator(i, moved, array, cmp);
   640                     siftUpUsingComparator(i, moved, es, cmp);
   645             }
   641             }
   646         }
   642         }
   647         size = n;
   643         size = n;
   648     }
   644     }
   649 
   645 
   672         }
   668         }
   673     }
   669     }
   674 
   670 
   675     /**
   671     /**
   676      * Identity-based version for use in Itr.remove.
   672      * Identity-based version for use in Itr.remove.
   677      */
   673      *
   678     void removeEQ(Object o) {
   674      * @param o element to be removed from this queue, if present
   679         final ReentrantLock lock = this.lock;
   675      */
   680         lock.lock();
   676     void removeEq(Object o) {
   681         try {
   677         final ReentrantLock lock = this.lock;
   682             Object[] array = queue;
   678         lock.lock();
       
   679         try {
       
   680             final Object[] es = queue;
   683             for (int i = 0, n = size; i < n; i++) {
   681             for (int i = 0, n = size; i < n; i++) {
   684                 if (o == array[i]) {
   682                 if (o == es[i]) {
   685                     removeAt(i);
   683                     removeAt(i);
   686                     break;
   684                     break;
   687                 }
   685                 }
   688             }
   686             }
   689         } finally {
   687         } finally {
   755      */
   753      */
   756     public void clear() {
   754     public void clear() {
   757         final ReentrantLock lock = this.lock;
   755         final ReentrantLock lock = this.lock;
   758         lock.lock();
   756         lock.lock();
   759         try {
   757         try {
   760             Object[] array = queue;
   758             final Object[] es = queue;
   761             int n = size;
   759             for (int i = 0, n = size; i < n; i++)
       
   760                 es[i] = null;
   762             size = 0;
   761             size = 0;
   763             for (int i = 0; i < n; i++)
       
   764                 array[i] = null;
       
   765         } finally {
   762         } finally {
   766             lock.unlock();
   763             lock.unlock();
   767         }
   764         }
   768     }
   765     }
   769 
   766 
   860      * Snapshot iterator that works off copy of underlying q array.
   857      * Snapshot iterator that works off copy of underlying q array.
   861      */
   858      */
   862     final class Itr implements Iterator<E> {
   859     final class Itr implements Iterator<E> {
   863         final Object[] array; // Array of all elements
   860         final Object[] array; // Array of all elements
   864         int cursor;           // index of next element to return
   861         int cursor;           // index of next element to return
   865         int lastRet;          // index of last element, or -1 if no such
   862         int lastRet = -1;     // index of last element, or -1 if no such
   866 
   863 
   867         Itr(Object[] array) {
   864         Itr(Object[] array) {
   868             lastRet = -1;
       
   869             this.array = array;
   865             this.array = array;
   870         }
   866         }
   871 
   867 
   872         public boolean hasNext() {
   868         public boolean hasNext() {
   873             return cursor < array.length;
   869             return cursor < array.length;
   880         }
   876         }
   881 
   877 
   882         public void remove() {
   878         public void remove() {
   883             if (lastRet < 0)
   879             if (lastRet < 0)
   884                 throw new IllegalStateException();
   880                 throw new IllegalStateException();
   885             removeEQ(array[lastRet]);
   881             removeEq(array[lastRet]);
   886             lastRet = -1;
   882             lastRet = -1;
       
   883         }
       
   884 
       
   885         public void forEachRemaining(Consumer<? super E> action) {
       
   886             Objects.requireNonNull(action);
       
   887             final Object[] es = array;
       
   888             int i;
       
   889             if ((i = cursor) < es.length) {
       
   890                 lastRet = -1;
       
   891                 cursor = es.length;
       
   892                 for (; i < es.length; i++)
       
   893                     action.accept((E) es[i]);
       
   894                 lastRet = es.length - 1;
       
   895             }
   887         }
   896         }
   888     }
   897     }
   889 
   898 
   890     /**
   899     /**
   891      * Saves this queue to a stream (that is, serializes it).
   900      * Saves this queue to a stream (that is, serializes it).
   922         throws java.io.IOException, ClassNotFoundException {
   931         throws java.io.IOException, ClassNotFoundException {
   923         try {
   932         try {
   924             s.defaultReadObject();
   933             s.defaultReadObject();
   925             int sz = q.size();
   934             int sz = q.size();
   926             SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, sz);
   935             SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, sz);
   927             this.queue = new Object[sz];
   936             this.queue = new Object[Math.max(1, sz)];
   928             comparator = q.comparator();
   937             comparator = q.comparator();
   929             addAll(q);
   938             addAll(q);
   930         } finally {
   939         } finally {
   931             q = null;
   940             q = null;
   932         }
   941         }
   961         }
   970         }
   962 
   971 
   963         public void forEachRemaining(Consumer<? super E> action) {
   972         public void forEachRemaining(Consumer<? super E> action) {
   964             Objects.requireNonNull(action);
   973             Objects.requireNonNull(action);
   965             final int hi = getFence(), lo = index;
   974             final int hi = getFence(), lo = index;
   966             final Object[] a = array;
   975             final Object[] es = array;
   967             index = hi;                 // ensure exhaustion
   976             index = hi;                 // ensure exhaustion
   968             for (int i = lo; i < hi; i++)
   977             for (int i = lo; i < hi; i++)
   969                 action.accept((E) a[i]);
   978                 action.accept((E) es[i]);
   970         }
   979         }
   971 
   980 
   972         public boolean tryAdvance(Consumer<? super E> action) {
   981         public boolean tryAdvance(Consumer<? super E> action) {
   973             Objects.requireNonNull(action);
   982             Objects.requireNonNull(action);
   974             if (getFence() > index && index >= 0) {
   983             if (getFence() > index && index >= 0) {
  1006      */
  1015      */
  1007     public Spliterator<E> spliterator() {
  1016     public Spliterator<E> spliterator() {
  1008         return new PBQSpliterator();
  1017         return new PBQSpliterator();
  1009     }
  1018     }
  1010 
  1019 
       
  1020     /**
       
  1021      * @throws NullPointerException {@inheritDoc}
       
  1022      */
       
  1023     public boolean removeIf(Predicate<? super E> filter) {
       
  1024         Objects.requireNonNull(filter);
       
  1025         return bulkRemove(filter);
       
  1026     }
       
  1027 
       
  1028     /**
       
  1029      * @throws NullPointerException {@inheritDoc}
       
  1030      */
       
  1031     public boolean removeAll(Collection<?> c) {
       
  1032         Objects.requireNonNull(c);
       
  1033         return bulkRemove(e -> c.contains(e));
       
  1034     }
       
  1035 
       
  1036     /**
       
  1037      * @throws NullPointerException {@inheritDoc}
       
  1038      */
       
  1039     public boolean retainAll(Collection<?> c) {
       
  1040         Objects.requireNonNull(c);
       
  1041         return bulkRemove(e -> !c.contains(e));
       
  1042     }
       
  1043 
       
  1044     // A tiny bit set implementation
       
  1045 
       
  1046     private static long[] nBits(int n) {
       
  1047         return new long[((n - 1) >> 6) + 1];
       
  1048     }
       
  1049     private static void setBit(long[] bits, int i) {
       
  1050         bits[i >> 6] |= 1L << i;
       
  1051     }
       
  1052     private static boolean isClear(long[] bits, int i) {
       
  1053         return (bits[i >> 6] & (1L << i)) == 0;
       
  1054     }
       
  1055 
       
  1056     /** Implementation of bulk remove methods. */
       
  1057     private boolean bulkRemove(Predicate<? super E> filter) {
       
  1058         final ReentrantLock lock = this.lock;
       
  1059         lock.lock();
       
  1060         try {
       
  1061             final Object[] es = queue;
       
  1062             final int end = size;
       
  1063             int i;
       
  1064             // Optimize for initial run of survivors
       
  1065             for (i = 0; i < end && !filter.test((E) es[i]); i++)
       
  1066                 ;
       
  1067             if (i >= end)
       
  1068                 return false;
       
  1069             // Tolerate predicates that reentrantly access the
       
  1070             // collection for read, so traverse once to find elements
       
  1071             // to delete, a second pass to physically expunge.
       
  1072             final int beg = i;
       
  1073             final long[] deathRow = nBits(end - beg);
       
  1074             deathRow[0] = 1L;   // set bit 0
       
  1075             for (i = beg + 1; i < end; i++)
       
  1076                 if (filter.test((E) es[i]))
       
  1077                     setBit(deathRow, i - beg);
       
  1078             int w = beg;
       
  1079             for (i = beg; i < end; i++)
       
  1080                 if (isClear(deathRow, i - beg))
       
  1081                     es[w++] = es[i];
       
  1082             for (i = size = w; i < end; i++)
       
  1083                 es[i] = null;
       
  1084             heapify();
       
  1085             return true;
       
  1086         } finally {
       
  1087             lock.unlock();
       
  1088         }
       
  1089     }
       
  1090 
       
  1091     /**
       
  1092      * @throws NullPointerException {@inheritDoc}
       
  1093      */
       
  1094     public void forEach(Consumer<? super E> action) {
       
  1095         Objects.requireNonNull(action);
       
  1096         final ReentrantLock lock = this.lock;
       
  1097         lock.lock();
       
  1098         try {
       
  1099             final Object[] es = queue;
       
  1100             for (int i = 0, n = size; i < n; i++)
       
  1101                 action.accept((E) es[i]);
       
  1102         } finally {
       
  1103             lock.unlock();
       
  1104         }
       
  1105     }
       
  1106 
  1011     // VarHandle mechanics
  1107     // VarHandle mechanics
  1012     private static final VarHandle ALLOCATIONSPINLOCK;
  1108     private static final VarHandle ALLOCATIONSPINLOCK;
  1013     static {
  1109     static {
  1014         try {
  1110         try {
  1015             MethodHandles.Lookup l = MethodHandles.lookup();
  1111             MethodHandles.Lookup l = MethodHandles.lookup();