diff options
Diffstat (limited to 'luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java')
-rw-r--r-- | luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java index 3ed0a7c..a0a26fd 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java @@ -1,7 +1,7 @@ /* * Written by Doug Lea and Martin Buchholz with assistance from members of * JCP JSR-166 Expert Group and released to the public domain, as explained - * at http://creativecommons.org/licenses/publicdomain + * at http://creativecommons.org/publicdomain/zero/1.0/ */ package java.util.concurrent; @@ -47,7 +47,14 @@ import java.util.Queue; * <p>Beware that, unlike in most collections, the {@code size} method * is <em>NOT</em> a constant-time operation. Because of the * asynchronous nature of these queues, determining the current number - * of elements requires a traversal of the elements. + * of elements requires a traversal of the elements, and so may report + * inaccurate results if this collection is modified during traversal. + * Additionally, the bulk operations {@code addAll}, + * {@code removeAll}, {@code retainAll}, {@code containsAll}, + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed + * to be performed atomically. For example, an iterator operating + * concurrently with an {@code addAll} operation might view only some + * of the added elements. * * <p>This class and its iterator implement all of the <em>optional</em> * methods of the {@link Queue} and {@link Iterator} interfaces. @@ -165,12 +172,22 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE = - sun.misc.Unsafe.getUnsafe(); - private static final long nextOffset = - objectFieldOffset(UNSAFE, "next", Node.class); - private static final long itemOffset = - objectFieldOffset(UNSAFE, "item", Node.class); + private static final sun.misc.Unsafe UNSAFE; + private static final long itemOffset; + private static final long nextOffset; + + static { + try { + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class<?> k = Node.class; + itemOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("item")); + nextOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("next")); + } catch (Exception e) { + throw new Error(e); + } + } } /** @@ -563,8 +580,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> * The following code can be used to dump the queue into a newly * allocated array of {@code String}: * - * <pre> - * String[] y = x.toArray(new String[0]);</pre> + * <pre> {@code String[] y = x.toArray(new String[0]);}</pre> * * Note that {@code toArray(new Object[0])} is identical in function to * {@code toArray()}. @@ -761,14 +777,6 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> throw new NullPointerException(); } - // Unsafe mechanics - - private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); - private static final long headOffset = - objectFieldOffset(UNSAFE, "head", ConcurrentLinkedQueue.class); - private static final long tailOffset = - objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedQueue.class); - private boolean casTail(Node<E> cmp, Node<E> val) { return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); } @@ -777,15 +785,21 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); } - static long objectFieldOffset(sun.misc.Unsafe UNSAFE, - String field, Class<?> klazz) { + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE; + private static final long headOffset; + private static final long tailOffset; + static { try { - return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); - } catch (NoSuchFieldException e) { - // Convert Exception to corresponding Error - NoSuchFieldError error = new NoSuchFieldError(field); - error.initCause(e); - throw error; + UNSAFE = sun.misc.Unsafe.getUnsafe(); + Class<?> k = ConcurrentLinkedQueue.class; + headOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("head")); + tailOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("tail")); + } catch (Exception e) { + throw new Error(e); } } } |