21 |
|
* producer. The <em>tail</em> of the queue is that element that has |
22 |
|
* been on the queue the shortest time for some producer. |
23 |
|
* |
24 |
< |
* <p>Beware that, unlike in most collections, the <tt>size</tt> |
24 |
> |
* <p>Beware that, unlike in most collections, the {@code size} |
25 |
|
* method is <em>NOT</em> a constant-time operation. Because of the |
26 |
|
* asynchronous nature of these queues, determining the current number |
27 |
|
* of elements requires a traversal of the elements. |
332 |
|
return t; |
333 |
|
} |
334 |
|
} |
335 |
< |
} |
335 |
> |
} |
336 |
|
|
337 |
|
/** |
338 |
|
* Gets rid of cancelled node s with original predecessor pred. |
359 |
|
QNode t = getValidatedTail(); |
360 |
|
if (s != t) { // If not tail, try to unsplice |
361 |
|
QNode sn = s.next; // s.next == s means s already off list |
362 |
< |
if (sn == s || pred.casNext(s, sn)) |
362 |
> |
if (sn == s || pred.casNext(s, sn)) |
363 |
|
break; |
364 |
|
} |
365 |
|
else if (oldpred == pred || // Already saved |
374 |
|
* @return current cleanMe node (or null) |
375 |
|
*/ |
376 |
|
private QNode reclean() { |
377 |
< |
/* |
377 |
> |
/* |
378 |
|
* cleanMe is, or at one time was, predecessor of cancelled |
379 |
|
* node s that was the tail so could not be unspliced. If s |
380 |
|
* is no longer the tail, try to unsplice if necessary and |
383 |
|
* points to a cancelled node that must be unspliced -- if |
384 |
|
* not, we can (must) clear cleanMe without unsplicing. |
385 |
|
* This can loop only due to contention on casNext or |
386 |
< |
* clearing cleanMe. |
386 |
> |
* clearing cleanMe. |
387 |
|
*/ |
388 |
|
QNode pred; |
389 |
|
while ((pred = cleanMe.get()) != null) { |
390 |
|
QNode t = getValidatedTail(); |
391 |
|
QNode s = pred.next; |
392 |
< |
if (s != t) { |
392 |
> |
if (s != t) { |
393 |
|
QNode sn; |
394 |
|
if (s == null || s == pred || s.get() != s || |
395 |
|
(sn = s.next) == s || pred.casNext(s, sn)) |
402 |
|
} |
403 |
|
|
404 |
|
/** |
405 |
< |
* Creates an initially empty <tt>LinkedTransferQueue</tt>. |
405 |
> |
* Creates an initially empty {@code LinkedTransferQueue}. |
406 |
|
*/ |
407 |
|
public LinkedTransferQueue() { |
408 |
|
QNode dummy = new QNode(null, false); |
412 |
|
} |
413 |
|
|
414 |
|
/** |
415 |
< |
* Creates a <tt>LinkedTransferQueue</tt> |
415 |
> |
* Creates a {@code LinkedTransferQueue} |
416 |
|
* initially containing the elements of the given collection, |
417 |
|
* added in traversal order of the collection's iterator. |
418 |
|
* @param c the collection of elements to initially contain |
655 |
|
|
656 |
|
/** |
657 |
|
* Returns the number of elements in this queue. If this queue |
658 |
< |
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns |
659 |
< |
* <tt>Integer.MAX_VALUE</tt>. |
658 |
> |
* contains more than {@code Integer.MAX_VALUE} elements, returns |
659 |
> |
* {@code Integer.MAX_VALUE}. |
660 |
|
* |
661 |
|
* <p>Beware that, unlike in most collections, this method is |
662 |
|
* <em>NOT</em> a constant-time operation. Because of the |
697 |
|
/** |
698 |
|
* Save the state to a stream (that is, serialize it). |
699 |
|
* |
700 |
< |
* @serialData All of the elements (each an <tt>E</tt>) in |
700 |
> |
* @serialData All of the elements (each an {@code E}) in |
701 |
|
* the proper order, followed by a null |
702 |
|
* @param s the stream |
703 |
|
*/ |
758 |
|
|
759 |
|
private void resetHeadAndTail() { |
760 |
|
QNode dummy = new QNode(null, false); |
761 |
< |
_unsafe.putObjectVolatile(this, headOffset, |
761 |
> |
_unsafe.putObjectVolatile(this, headOffset, |
762 |
|
new PaddedAtomicReference<QNode>(dummy)); |
763 |
< |
_unsafe.putObjectVolatile(this, tailOffset, |
763 |
> |
_unsafe.putObjectVolatile(this, tailOffset, |
764 |
|
new PaddedAtomicReference<QNode>(dummy)); |
765 |
|
_unsafe.putObjectVolatile(this, cleanMeOffset, |
766 |
|
new PaddedAtomicReference<QNode>(null)); |