359 |
|
} |
360 |
|
} |
361 |
|
|
362 |
– |
|
362 |
|
public String toString() { |
363 |
|
final ReentrantLock lock = this.lock; |
364 |
|
lock.lock(); |
487 |
|
/** |
488 |
|
* Returns an iterator over the elements in this queue. The |
489 |
|
* iterator does not return the elements in any particular order. |
491 |
– |
* The returned iterator is a thread-safe "fast-fail" iterator |
492 |
– |
* that will throw {@link ConcurrentModificationException} upon |
493 |
– |
* detected interference. |
490 |
|
* |
491 |
|
* @return an iterator over the elements in this queue |
492 |
|
*/ |
493 |
|
public Iterator<E> iterator() { |
494 |
< |
final ReentrantLock lock = this.lock; |
499 |
< |
lock.lock(); |
500 |
< |
try { |
501 |
< |
return new Itr<E>(q.iterator()); |
502 |
< |
} finally { |
503 |
< |
lock.unlock(); |
504 |
< |
} |
494 |
> |
return new Itr<E>(toArray()); |
495 |
|
} |
496 |
|
|
497 |
+ |
/** |
498 |
+ |
* Snapshot iterator that works off copy of underlying q array. |
499 |
+ |
*/ |
500 |
|
private class Itr<E> implements Iterator<E> { |
501 |
< |
private final Iterator<E> iter; |
502 |
< |
Itr(Iterator<E> i) { |
503 |
< |
iter = i; |
501 |
> |
final Object[] array; // Array of all elements |
502 |
> |
int cursor; // index of next element to return; |
503 |
> |
int lastRet; // index of last element, or -1 if no such |
504 |
> |
|
505 |
> |
Itr(Object[] array) { |
506 |
> |
lastRet = -1; |
507 |
> |
this.array = array; |
508 |
|
} |
509 |
|
|
510 |
|
public boolean hasNext() { |
511 |
< |
/* |
515 |
< |
* No sync -- we rely on underlying hasNext to be |
516 |
< |
* stateless, in which case we can return true by mistake |
517 |
< |
* only when next() will subsequently throw |
518 |
< |
* ConcurrentModificationException. |
519 |
< |
*/ |
520 |
< |
return iter.hasNext(); |
511 |
> |
return cursor < array.length; |
512 |
|
} |
513 |
|
|
514 |
|
public E next() { |
515 |
< |
ReentrantLock lock = PriorityBlockingQueue.this.lock; |
516 |
< |
lock.lock(); |
517 |
< |
try { |
518 |
< |
return iter.next(); |
528 |
< |
} finally { |
529 |
< |
lock.unlock(); |
530 |
< |
} |
515 |
> |
if (cursor >= array.length) |
516 |
> |
throw new NoSuchElementException(); |
517 |
> |
lastRet = cursor; |
518 |
> |
return (E)array[cursor++]; |
519 |
|
} |
520 |
|
|
521 |
|
public void remove() { |
522 |
< |
ReentrantLock lock = PriorityBlockingQueue.this.lock; |
522 |
> |
if (lastRet < 0) |
523 |
> |
throw new IllegalStateException(); |
524 |
> |
Object x = array[lastRet]; |
525 |
> |
lastRet = -1; |
526 |
> |
// Traverse underlying queue to find == element, |
527 |
> |
// not just a .equals element. |
528 |
|
lock.lock(); |
529 |
|
try { |
530 |
< |
iter.remove(); |
530 |
> |
for (Iterator it = q.iterator(); it.hasNext(); ) { |
531 |
> |
if (it.next() == x) { |
532 |
> |
it.remove(); |
533 |
> |
return; |
534 |
> |
} |
535 |
> |
} |
536 |
|
} finally { |
537 |
|
lock.unlock(); |
538 |
|
} |