ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentLinkedQueue.java
Revision: 1.56
Committed: Tue Aug 24 22:30:24 2010 UTC (13 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.55: +9 -3 lines
Log Message:
restore historic behavior of q.addAll(q)

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/licenses/publicdomain
5 */
6
7 package java.util.concurrent;
8
9 import java.util.AbstractQueue;
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Iterator;
13 import java.util.NoSuchElementException;
14 import java.util.Queue;
15
16 /**
17 * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
18 * This queue orders elements FIFO (first-in-first-out).
19 * The <em>head</em> of the queue is that element that has been on the
20 * queue the longest time.
21 * The <em>tail</em> of the queue is that element that has been on the
22 * queue the shortest time. New elements
23 * are inserted at the tail of the queue, and the queue retrieval
24 * operations obtain elements at the head of the queue.
25 * A {@code ConcurrentLinkedQueue} is an appropriate choice when
26 * many threads will share access to a common collection.
27 * Like most other concurrent collection implementations, this class
28 * does not permit the use of {@code null} elements.
29 *
30 * <p>This implementation employs an efficient &quot;wait-free&quot;
31 * algorithm based on one described in <a
32 * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
33 * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
34 * Algorithms</a> by Maged M. Michael and Michael L. Scott.
35 *
36 * <p>Iterators are <i>weakly consistent</i>, returning elements
37 * reflecting the state of the queue at some point at or since the
38 * creation of the iterator. They do <em>not</em> throw {@link
39 * ConcurrentModificationException}, and may proceed concurrently with
40 * other operations. Elements contained in the queue since the creation
41 * of the iterator will be returned exactly once.
42 *
43 * <p>Beware that, unlike in most collections, the {@code size} method
44 * is <em>NOT</em> a constant-time operation. Because of the
45 * asynchronous nature of these queues, determining the current number
46 * of elements requires a traversal of the elements.
47 *
48 * <p>This class and its iterator implement all of the <em>optional</em>
49 * methods of the {@link Queue} and {@link Iterator} interfaces.
50 *
51 * <p>Memory consistency effects: As with other concurrent
52 * collections, actions in a thread prior to placing an object into a
53 * {@code ConcurrentLinkedQueue}
54 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
55 * actions subsequent to the access or removal of that element from
56 * the {@code ConcurrentLinkedQueue} in another thread.
57 *
58 * <p>This class is a member of the
59 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
60 * Java Collections Framework</a>.
61 *
62 * @since 1.5
63 * @author Doug Lea
64 * @param <E> the type of elements held in this collection
65 *
66 */
67 public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
68 implements Queue<E>, java.io.Serializable {
69 private static final long serialVersionUID = 196745693267521676L;
70
71 /*
72 * This is a modification of the Michael & Scott algorithm,
73 * adapted for a garbage-collected environment, with support for
74 * interior node deletion (to support remove(Object)). For
75 * explanation, read the paper.
76 *
77 * Note that like most non-blocking algorithms in this package,
78 * this implementation relies on the fact that in garbage
79 * collected systems, there is no possibility of ABA problems due
80 * to recycled nodes, so there is no need to use "counted
81 * pointers" or related techniques seen in versions used in
82 * non-GC'ed settings.
83 *
84 * The fundamental invariants are:
85 * - There is exactly one (last) Node with a null next reference,
86 * which is CASed when enqueueing. This last Node can be
87 * reached in O(1) time from tail, but tail is merely an
88 * optimization - it can always be reached in O(N) time from
89 * head as well.
90 * - The elements contained in the queue are the non-null items in
91 * Nodes that are reachable from head. CASing the item
92 * reference of a Node to null atomically removes it from the
93 * queue. Reachability of all elements from head must remain
94 * true even in the case of concurrent modifications that cause
95 * head to advance. A dequeued Node may remain in use
96 * indefinitely due to creation of an Iterator or simply a
97 * poll() that has lost its time slice.
98 *
99 * The above might appear to imply that all Nodes are GC-reachable
100 * from a predecessor dequeued Node. That would cause two problems:
101 * - allow a rogue Iterator to cause unbounded memory retention
102 * - cause cross-generational linking of old Nodes to new Nodes if
103 * a Node was tenured while live, which generational GCs have a
104 * hard time dealing with, causing repeated major collections.
105 * However, only non-deleted Nodes need to be reachable from
106 * dequeued Nodes, and reachability does not necessarily have to
107 * be of the kind understood by the GC. We use the trick of
108 * linking a Node that has just been dequeued to itself. Such a
109 * self-link implicitly means to advance to head.
110 *
111 * Both head and tail are permitted to lag. In fact, failing to
112 * update them every time one could is a significant optimization
113 * (fewer CASes). This is controlled by local "hops" variables
114 * that only trigger helping-CASes after experiencing multiple
115 * lags.
116 *
117 * Since head and tail are updated concurrently and independently,
118 * it is possible for tail to lag behind head (why not)?
119 *
120 * CASing a Node's item reference to null atomically removes the
121 * element from the queue. Iterators skip over Nodes with null
122 * items. Prior implementations of this class had a race between
123 * poll() and remove(Object) where the same element would appear
124 * to be successfully removed by two concurrent operations. The
125 * method remove(Object) also lazily unlinks deleted Nodes, but
126 * this is merely an optimization.
127 *
128 * When constructing a Node (before enqueuing it) we avoid paying
129 * for a volatile write to item by using lazySet instead of a
130 * normal write. This allows the cost of enqueue to be
131 * "one-and-a-half" CASes.
132 *
133 * Both head and tail may or may not point to a Node with a
134 * non-null item. If the queue is empty, all items must of course
135 * be null. Upon creation, both head and tail refer to a dummy
136 * Node with null item. Both head and tail are only updated using
137 * CAS, so they never regress, although again this is merely an
138 * optimization.
139 */
140
141 private static class Node<E> {
142 private volatile E item;
143 private volatile Node<E> next;
144
145 Node(E item) {
146 // Piggyback on imminent casNext()
147 lazySetItem(item);
148 }
149
150 E getItem() {
151 return item;
152 }
153
154 boolean casItem(E cmp, E val) {
155 return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
156 }
157
158 void setItem(E val) {
159 item = val;
160 }
161
162 void lazySetItem(E val) {
163 UNSAFE.putOrderedObject(this, itemOffset, val);
164 }
165
166 void lazySetNext(Node<E> val) {
167 UNSAFE.putOrderedObject(this, nextOffset, val);
168 }
169
170 boolean casNext(Node<E> cmp, Node<E> val) {
171 return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
172 }
173
174 // Unsafe mechanics
175
176 private static final sun.misc.Unsafe UNSAFE =
177 sun.misc.Unsafe.getUnsafe();
178 private static final long nextOffset =
179 objectFieldOffset(UNSAFE, "next", Node.class);
180 private static final long itemOffset =
181 objectFieldOffset(UNSAFE, "item", Node.class);
182 }
183
184 /**
185 * A node from which the first live (non-deleted) node (if any)
186 * can be reached in O(1) time.
187 * Invariants:
188 * - all live nodes are reachable from head via succ()
189 * - head != null
190 * - (tmp = head).next != tmp || tmp != head
191 * Non-invariants:
192 * - head.item may or may not be null.
193 * - it is permitted for tail to lag behind head, that is, for tail
194 * to not be reachable from head!
195 */
196 private transient volatile Node<E> head;
197
198 /**
199 * A node from which the last node on list (that is, the unique
200 * node with node.next == null) can be reached in O(1) time.
201 * Invariants:
202 * - the last node is always reachable from tail via succ()
203 * - tail != null
204 * Non-invariants:
205 * - tail.item may or may not be null.
206 * - it is permitted for tail to lag behind head, that is, for tail
207 * to not be reachable from head!
208 * - tail.next may or may not be self-pointing to tail.
209 */
210 private transient volatile Node<E> tail;
211
212
213 /**
214 * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
215 */
216 public ConcurrentLinkedQueue() {
217 head = tail = new Node<E>(null);
218 }
219
220 /**
221 * Creates a {@code ConcurrentLinkedQueue}
222 * initially containing the elements of the given collection,
223 * added in traversal order of the collection's iterator.
224 *
225 * @param c the collection of elements to initially contain
226 * @throws NullPointerException if the specified collection or any
227 * of its elements are null
228 */
229 public ConcurrentLinkedQueue(Collection<? extends E> c) {
230 Node<E> h = null, t = null;
231 for (E e : c) {
232 checkNotNull(e);
233 Node<E> newNode = new Node<E>(e);
234 if (h == null)
235 h = t = newNode;
236 else {
237 t.next = newNode;
238 t = newNode;
239 }
240 }
241 if (h == null)
242 h = t = new Node<E>(null);
243 head = h;
244 tail = t;
245 }
246
247 // Have to override just to update the javadoc
248
249 /**
250 * Inserts the specified element at the tail of this queue.
251 *
252 * @return {@code true} (as specified by {@link Collection#add})
253 * @throws NullPointerException if the specified element is null
254 */
255 public boolean add(E e) {
256 return offer(e);
257 }
258
259 /**
260 * We don't bother to update head or tail pointers if fewer than
261 * HOPS links from "true" location. We assume that volatile
262 * writes are significantly more expensive than volatile reads.
263 */
264 private static final int HOPS = 1;
265
266 /**
267 * Try to CAS head to p. If successful, repoint old head to itself
268 * as sentinel for succ(), below.
269 */
270 final void updateHead(Node<E> h, Node<E> p) {
271 if (h != p && casHead(h, p))
272 h.lazySetNext(h);
273 }
274
275 /**
276 * Returns the successor of p, or the head node if p.next has been
277 * linked to self, which will only be true if traversing with a
278 * stale pointer that is now off the list.
279 */
280 final Node<E> succ(Node<E> p) {
281 Node<E> next = p.next;
282 return (p == next) ? head : next;
283 }
284
285 /**
286 * Inserts the specified element at the tail of this queue.
287 *
288 * @return {@code true} (as specified by {@link Queue#offer})
289 * @throws NullPointerException if the specified element is null
290 */
291 public boolean offer(E e) {
292 checkNotNull(e);
293 Node<E> n = new Node<E>(e);
294 retry:
295 for (;;) {
296 Node<E> t = tail;
297 Node<E> p = t;
298 for (int hops = 0; ; hops++) {
299 Node<E> next = succ(p);
300 if (next != null) {
301 if (hops > HOPS && t != tail)
302 continue retry;
303 p = next;
304 } else if (p.casNext(null, n)) {
305 if (hops >= HOPS)
306 casTail(t, n); // Failure is OK.
307 return true;
308 } else {
309 p = succ(p);
310 }
311 }
312 }
313 }
314
315 public E poll() {
316 Node<E> h = head;
317 Node<E> p = h;
318 for (int hops = 0; ; hops++) {
319 E item = p.getItem();
320
321 if (item != null && p.casItem(item, null)) {
322 if (hops >= HOPS) {
323 Node<E> q = p.next;
324 updateHead(h, (q != null) ? q : p);
325 }
326 return item;
327 }
328 Node<E> next = succ(p);
329 if (next == null) {
330 updateHead(h, p);
331 break;
332 }
333 p = next;
334 }
335 return null;
336 }
337
338 public E peek() {
339 Node<E> h = head;
340 Node<E> p = h;
341 E item;
342 for (;;) {
343 item = p.getItem();
344 if (item != null)
345 break;
346 Node<E> next = succ(p);
347 if (next == null) {
348 break;
349 }
350 p = next;
351 }
352 updateHead(h, p);
353 return item;
354 }
355
356 /**
357 * Returns the first live (non-deleted) node on list, or null if none.
358 * This is yet another variant of poll/peek; here returning the
359 * first node, not element. We could make peek() a wrapper around
360 * first(), but that would cost an extra volatile read of item,
361 * and the need to add a retry loop to deal with the possibility
362 * of losing a race to a concurrent poll().
363 */
364 Node<E> first() {
365 Node<E> h = head;
366 Node<E> p = h;
367 Node<E> result;
368 for (;;) {
369 E item = p.getItem();
370 if (item != null) {
371 result = p;
372 break;
373 }
374 Node<E> next = succ(p);
375 if (next == null) {
376 result = null;
377 break;
378 }
379 p = next;
380 }
381 updateHead(h, p);
382 return result;
383 }
384
385 /**
386 * Returns {@code true} if this queue contains no elements.
387 *
388 * @return {@code true} if this queue contains no elements
389 */
390 public boolean isEmpty() {
391 return first() == null;
392 }
393
394 /**
395 * Returns the number of elements in this queue. If this queue
396 * contains more than {@code Integer.MAX_VALUE} elements, returns
397 * {@code Integer.MAX_VALUE}.
398 *
399 * <p>Beware that, unlike in most collections, this method is
400 * <em>NOT</em> a constant-time operation. Because of the
401 * asynchronous nature of these queues, determining the current
402 * number of elements requires an O(n) traversal.
403 * Additionally, if elements are added or removed during execution
404 * of this method, the returned result may be inaccurate. Thus,
405 * this method is typically not very useful in concurrent
406 * applications.
407 *
408 * @return the number of elements in this queue
409 */
410 public int size() {
411 int count = 0;
412 for (Node<E> p = first(); p != null; p = succ(p)) {
413 if (p.getItem() != null) {
414 // Collections.size() spec says to max out
415 if (++count == Integer.MAX_VALUE)
416 break;
417 }
418 }
419 return count;
420 }
421
422 /**
423 * Returns {@code true} if this queue contains the specified element.
424 * More formally, returns {@code true} if and only if this queue contains
425 * at least one element {@code e} such that {@code o.equals(e)}.
426 *
427 * @param o object to be checked for containment in this queue
428 * @return {@code true} if this queue contains the specified element
429 */
430 public boolean contains(Object o) {
431 if (o == null) return false;
432 for (Node<E> p = first(); p != null; p = succ(p)) {
433 E item = p.getItem();
434 if (item != null &&
435 o.equals(item))
436 return true;
437 }
438 return false;
439 }
440
441 /**
442 * Removes a single instance of the specified element from this queue,
443 * if it is present. More formally, removes an element {@code e} such
444 * that {@code o.equals(e)}, if this queue contains one or more such
445 * elements.
446 * Returns {@code true} if this queue contained the specified element
447 * (or equivalently, if this queue changed as a result of the call).
448 *
449 * @param o element to be removed from this queue, if present
450 * @return {@code true} if this queue changed as a result of the call
451 */
452 public boolean remove(Object o) {
453 if (o == null) return false;
454 Node<E> pred = null;
455 for (Node<E> p = first(); p != null; p = succ(p)) {
456 E item = p.getItem();
457 if (item != null &&
458 o.equals(item) &&
459 p.casItem(item, null)) {
460 Node<E> next = succ(p);
461 if (pred != null && next != null)
462 pred.casNext(p, next);
463 return true;
464 }
465 pred = p;
466 }
467 return false;
468 }
469
470 /**
471 * Appends all of the elements in the specified collection to the end of
472 * this queue, in the order that they are returned by the specified
473 * collection's iterator. Attempts to {@code addAll} of a queue to
474 * itself result in {@code IllegalArgumentException}.
475 *
476 * @param c the elements to be inserted into this queue
477 * @return {@code true} if this queue changed as a result of the call
478 * @throws NullPointerException if the specified collection or any
479 * of its elements are null
480 * @throws IllegalArgumentException if the collection is this queue
481 */
482 public boolean addAll(Collection<? extends E> c) {
483 if (c == this)
484 // As historically specified in AbstractQueue#addAll
485 throw new IllegalArgumentException();
486
487 // Copy c into a private chain of Nodes
488 Node<E> splice = null, last = null;
489 for (E e : c) {
490 checkNotNull(e);
491 Node<E> newNode = new Node<E>(e);
492 if (splice == null)
493 splice = last = newNode;
494 else {
495 last.next = newNode;
496 last = newNode;
497 }
498 }
499 if (splice == null)
500 return false;
501
502 // Atomically splice the chain as the tail of this collection
503 retry:
504 for (;;) {
505 for (Node<E> t = tail, p = t;;) {
506 Node<E> next = succ(p);
507 if (next != null) {
508 if (t != tail)
509 continue retry;
510 p = next;
511 } else if (p.casNext(null, splice)) {
512 if (! casTail(t, last)) {
513 // Try a little harder to update tail,
514 // since we may be adding many elements.
515 t = tail;
516 if (last.next == null)
517 casTail(t, last);
518 }
519 return true;
520 } else {
521 p = succ(p);
522 }
523 }
524 }
525 }
526
527 /**
528 * Returns an array containing all of the elements in this queue, in
529 * proper sequence.
530 *
531 * <p>The returned array will be "safe" in that no references to it are
532 * maintained by this queue. (In other words, this method must allocate
533 * a new array). The caller is thus free to modify the returned array.
534 *
535 * <p>This method acts as bridge between array-based and collection-based
536 * APIs.
537 *
538 * @return an array containing all of the elements in this queue
539 */
540 public Object[] toArray() {
541 // Use ArrayList to deal with resizing.
542 ArrayList<E> al = new ArrayList<E>();
543 for (Node<E> p = first(); p != null; p = succ(p)) {
544 E item = p.getItem();
545 if (item != null)
546 al.add(item);
547 }
548 return al.toArray();
549 }
550
551 /**
552 * Returns an array containing all of the elements in this queue, in
553 * proper sequence; the runtime type of the returned array is that of
554 * the specified array. If the queue fits in the specified array, it
555 * is returned therein. Otherwise, a new array is allocated with the
556 * runtime type of the specified array and the size of this queue.
557 *
558 * <p>If this queue fits in the specified array with room to spare
559 * (i.e., the array has more elements than this queue), the element in
560 * the array immediately following the end of the queue is set to
561 * {@code null}.
562 *
563 * <p>Like the {@link #toArray()} method, this method acts as bridge between
564 * array-based and collection-based APIs. Further, this method allows
565 * precise control over the runtime type of the output array, and may,
566 * under certain circumstances, be used to save allocation costs.
567 *
568 * <p>Suppose {@code x} is a queue known to contain only strings.
569 * The following code can be used to dump the queue into a newly
570 * allocated array of {@code String}:
571 *
572 * <pre>
573 * String[] y = x.toArray(new String[0]);</pre>
574 *
575 * Note that {@code toArray(new Object[0])} is identical in function to
576 * {@code toArray()}.
577 *
578 * @param a the array into which the elements of the queue are to
579 * be stored, if it is big enough; otherwise, a new array of the
580 * same runtime type is allocated for this purpose
581 * @return an array containing all of the elements in this queue
582 * @throws ArrayStoreException if the runtime type of the specified array
583 * is not a supertype of the runtime type of every element in
584 * this queue
585 * @throws NullPointerException if the specified array is null
586 */
587 @SuppressWarnings("unchecked")
588 public <T> T[] toArray(T[] a) {
589 // try to use sent-in array
590 int k = 0;
591 Node<E> p;
592 for (p = first(); p != null && k < a.length; p = succ(p)) {
593 E item = p.getItem();
594 if (item != null)
595 a[k++] = (T)item;
596 }
597 if (p == null) {
598 if (k < a.length)
599 a[k] = null;
600 return a;
601 }
602
603 // If won't fit, use ArrayList version
604 ArrayList<E> al = new ArrayList<E>();
605 for (Node<E> q = first(); q != null; q = succ(q)) {
606 E item = q.getItem();
607 if (item != null)
608 al.add(item);
609 }
610 return al.toArray(a);
611 }
612
613 /**
614 * Returns an iterator over the elements in this queue in proper sequence.
615 * The elements will be returned in order from first (head) to last (tail).
616 *
617 * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
618 * will never throw {@link java.util.ConcurrentModificationException
619 * ConcurrentModificationException},
620 * and guarantees to traverse elements as they existed upon
621 * construction of the iterator, and may (but is not guaranteed to)
622 * reflect any modifications subsequent to construction.
623 *
624 * @return an iterator over the elements in this queue in proper sequence
625 */
626 public Iterator<E> iterator() {
627 return new Itr();
628 }
629
630 private class Itr implements Iterator<E> {
631 /**
632 * Next node to return item for.
633 */
634 private Node<E> nextNode;
635
636 /**
637 * nextItem holds on to item fields because once we claim
638 * that an element exists in hasNext(), we must return it in
639 * the following next() call even if it was in the process of
640 * being removed when hasNext() was called.
641 */
642 private E nextItem;
643
644 /**
645 * Node of the last returned item, to support remove.
646 */
647 private Node<E> lastRet;
648
649 Itr() {
650 advance();
651 }
652
653 /**
654 * Moves to next valid node and returns item to return for
655 * next(), or null if no such.
656 */
657 private E advance() {
658 lastRet = nextNode;
659 E x = nextItem;
660
661 Node<E> pred, p;
662 if (nextNode == null) {
663 p = first();
664 pred = null;
665 } else {
666 pred = nextNode;
667 p = succ(nextNode);
668 }
669
670 for (;;) {
671 if (p == null) {
672 nextNode = null;
673 nextItem = null;
674 return x;
675 }
676 E item = p.getItem();
677 if (item != null) {
678 nextNode = p;
679 nextItem = item;
680 return x;
681 } else {
682 // skip over nulls
683 Node<E> next = succ(p);
684 if (pred != null && next != null)
685 pred.casNext(p, next);
686 p = next;
687 }
688 }
689 }
690
691 public boolean hasNext() {
692 return nextNode != null;
693 }
694
695 public E next() {
696 if (nextNode == null) throw new NoSuchElementException();
697 return advance();
698 }
699
700 public void remove() {
701 Node<E> l = lastRet;
702 if (l == null) throw new IllegalStateException();
703 // rely on a future traversal to relink.
704 l.setItem(null);
705 lastRet = null;
706 }
707 }
708
709 /**
710 * Saves the state to a stream (that is, serializes it).
711 *
712 * @serialData All of the elements (each an {@code E}) in
713 * the proper order, followed by a null
714 * @param s the stream
715 */
716 private void writeObject(java.io.ObjectOutputStream s)
717 throws java.io.IOException {
718
719 // Write out any hidden stuff
720 s.defaultWriteObject();
721
722 // Write out all elements in the proper order.
723 for (Node<E> p = first(); p != null; p = succ(p)) {
724 Object item = p.getItem();
725 if (item != null)
726 s.writeObject(item);
727 }
728
729 // Use trailing null as sentinel
730 s.writeObject(null);
731 }
732
733 /**
734 * Reconstitutes the instance from a stream (that is, deserializes it).
735 * @param s the stream
736 */
737 private void readObject(java.io.ObjectInputStream s)
738 throws java.io.IOException, ClassNotFoundException {
739 s.defaultReadObject();
740
741 // Read in elements until trailing null sentinel found
742 Node<E> h = null, t = null;
743 Object item;
744 while ((item = s.readObject()) != null) {
745 @SuppressWarnings("unchecked")
746 Node<E> newNode = new Node<E>((E) item);
747 if (h == null)
748 h = t = newNode;
749 else {
750 t.next = newNode;
751 t = newNode;
752 }
753 }
754 if (h == null)
755 h = t = new Node<E>(null);
756 head = h;
757 tail = t;
758 }
759
760 /**
761 * Throws NullPointerException if argument is null.
762 *
763 * @param v the element
764 */
765 private static void checkNotNull(Object v) {
766 if (v == null)
767 throw new NullPointerException();
768 }
769
770 // Unsafe mechanics
771
772 private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
773 private static final long headOffset =
774 objectFieldOffset(UNSAFE, "head", ConcurrentLinkedQueue.class);
775 private static final long tailOffset =
776 objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedQueue.class);
777
778 private boolean casTail(Node<E> cmp, Node<E> val) {
779 return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
780 }
781
782 private boolean casHead(Node<E> cmp, Node<E> val) {
783 return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
784 }
785
786 private void lazySetHead(Node<E> val) {
787 UNSAFE.putOrderedObject(this, headOffset, val);
788 }
789
790 static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
791 String field, Class<?> klazz) {
792 try {
793 return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
794 } catch (NoSuchFieldException e) {
795 // Convert Exception to corresponding Error
796 NoSuchFieldError error = new NoSuchFieldError(field);
797 error.initCause(e);
798 throw error;
799 }
800 }
801 }