57 |
|
|
58 |
|
/** |
59 |
|
* Signal a waiting take. Called only from put/offer (which do not |
60 |
< |
* otherwise ordinarily have takeLock.) |
60 |
> |
* otherwise ordinarily lock takeLock.) |
61 |
|
*/ |
62 |
|
private void signalNotEmpty() { |
63 |
|
takeLock.lock(); |
390 |
|
try { |
391 |
|
int size = count.get(); |
392 |
|
if (a.length < size) |
393 |
< |
a = (T[])java.lang.reflect.Array.newInstance( |
394 |
< |
a.getClass().getComponentType(), size); |
395 |
< |
|
393 |
> |
a = (T[])java.lang.reflect.Array.newInstance |
394 |
> |
(a.getClass().getComponentType(), size); |
395 |
> |
|
396 |
|
int k = 0; |
397 |
|
for (Node p = head.next; p != null; p = p.next) |
398 |
|
a[k++] = (T)p.item; |
418 |
|
} |
419 |
|
|
420 |
|
private class Itr implements Iterator<E> { |
421 |
+ |
/* |
422 |
+ |
* Basic weak-consistent iterator. At all times hold the next |
423 |
+ |
* item to hand out so that if hasNext() reports true, we will |
424 |
+ |
* still have it to return even if lost race with a take etc. |
425 |
+ |
*/ |
426 |
|
Node<E> current; |
427 |
|
Node<E> lastRet; |
428 |
< |
|
424 |
< |
// for comodification checks |
425 |
< |
Node<E> expectedHead; |
426 |
< |
Node<E> expectedLast; |
427 |
< |
int expectedCount; |
428 |
> |
E currentElement; |
429 |
|
|
430 |
|
Itr() { |
431 |
|
fullyLock(); |
432 |
|
try { |
432 |
– |
expectedHead = head; |
433 |
|
current = head.next; |
434 |
< |
expectedLast = last; |
435 |
< |
expectedCount = count.get(); |
434 |
> |
if (current != null) |
435 |
> |
currentElement = current.item; |
436 |
|
} |
437 |
|
finally { |
438 |
|
fullyUnlock(); |
443 |
|
return current != null; |
444 |
|
} |
445 |
|
|
446 |
– |
private void checkForModification() { |
447 |
– |
if (expectedHead != head || |
448 |
– |
expectedLast != last || |
449 |
– |
expectedCount != count.get()) |
450 |
– |
throw new ConcurrentModificationException(); |
451 |
– |
} |
452 |
– |
|
446 |
|
public E next() { |
447 |
|
fullyLock(); |
448 |
|
try { |
449 |
|
if (current == null) |
450 |
|
throw new NoSuchElementException(); |
451 |
< |
checkForModification(); |
459 |
< |
E x = current.item; |
451 |
> |
E x = currentElement; |
452 |
|
lastRet = current; |
453 |
|
current = current.next; |
454 |
+ |
if (current != null) |
455 |
+ |
currentElement = current.item; |
456 |
|
return x; |
457 |
|
} |
458 |
|
finally { |
466 |
|
throw new IllegalStateException(); |
467 |
|
fullyLock(); |
468 |
|
try { |
475 |
– |
checkForModification(); |
469 |
|
Node<E> node = lastRet; |
470 |
|
lastRet = null; |
471 |
|
Node<E> trail = head; |
478 |
|
p.item = null; |
479 |
|
trail.next = p.next; |
480 |
|
int c = count.getAndDecrement(); |
488 |
– |
expectedHead = head; |
489 |
– |
expectedLast = last; |
490 |
– |
expectedCount = c; |
481 |
|
if (c == capacity) |
482 |
|
notFull.signalAll(); |
483 |
|
} |