328 * heavily contended queues. And so long as it is relatively |
328 * heavily contended queues. And so long as it is relatively |
329 * brief and "quiet", spinning does not much impact performance |
329 * brief and "quiet", spinning does not much impact performance |
330 * of less-contended queues. During spins threads check their |
330 * of less-contended queues. During spins threads check their |
331 * interrupt status and generate a thread-local random number |
331 * interrupt status and generate a thread-local random number |
332 * to decide to occasionally perform a Thread.yield. While |
332 * to decide to occasionally perform a Thread.yield. While |
333 * yield has underdefined specs, we assume that might it help, |
333 * yield has underdefined specs, we assume that it might help, |
334 * and will not hurt in limiting impact of spinning on busy |
334 * and will not hurt, in limiting impact of spinning on busy |
335 * systems. We also use smaller (1/2) spins for nodes that are |
335 * systems. We also use smaller (1/2) spins for nodes that are |
336 * not known to be front but whose predecessors have not |
336 * not known to be front but whose predecessors have not |
337 * blocked -- these "chained" spins avoid artifacts of |
337 * blocked -- these "chained" spins avoid artifacts of |
338 * front-of-queue rules which otherwise lead to alternating |
338 * front-of-queue rules which otherwise lead to alternating |
339 * nodes spinning vs blocking. Further, front threads that |
339 * nodes spinning vs blocking. Further, front threads that |
540 private static final long nextOffset; |
540 private static final long nextOffset; |
541 private static final long waiterOffset; |
541 private static final long waiterOffset; |
542 static { |
542 static { |
543 try { |
543 try { |
544 UNSAFE = sun.misc.Unsafe.getUnsafe(); |
544 UNSAFE = sun.misc.Unsafe.getUnsafe(); |
545 Class k = Node.class; |
545 Class<?> k = Node.class; |
546 itemOffset = UNSAFE.objectFieldOffset |
546 itemOffset = UNSAFE.objectFieldOffset |
547 (k.getDeclaredField("item")); |
547 (k.getDeclaredField("item")); |
548 nextOffset = UNSAFE.objectFieldOffset |
548 nextOffset = UNSAFE.objectFieldOffset |
549 (k.getDeclaredField("next")); |
549 (k.getDeclaredField("next")); |
550 waiterOffset = UNSAFE.objectFieldOffset |
550 waiterOffset = UNSAFE.objectFieldOffset |
625 if ((h = head) == null || |
625 if ((h = head) == null || |
626 (q = h.next) == null || !q.isMatched()) |
626 (q = h.next) == null || !q.isMatched()) |
627 break; // unless slack < 2 |
627 break; // unless slack < 2 |
628 } |
628 } |
629 LockSupport.unpark(p.waiter); |
629 LockSupport.unpark(p.waiter); |
630 return this.<E>cast(item); |
630 return LinkedTransferQueue.<E>cast(item); |
631 } |
631 } |
632 } |
632 } |
633 Node n = p.next; |
633 Node n = p.next; |
634 p = (p != n) ? n : (h = head); // Use head if p offlist |
634 p = (p != n) ? n : (h = head); // Use head if p offlist |
635 } |
635 } |
703 for (;;) { |
703 for (;;) { |
704 Object item = s.item; |
704 Object item = s.item; |
705 if (item != e) { // matched |
705 if (item != e) { // matched |
706 // assert item != s; |
706 // assert item != s; |
707 s.forgetContents(); // avoid garbage |
707 s.forgetContents(); // avoid garbage |
708 return this.<E>cast(item); |
708 return LinkedTransferQueue.<E>cast(item); |
709 } |
709 } |
710 if ((w.isInterrupted() || (timed && nanos <= 0)) && |
710 if ((w.isInterrupted() || (timed && nanos <= 0)) && |
711 s.casItem(e, s)) { // cancel |
711 s.casItem(e, s)) { // cancel |
712 unsplice(pred, s); |
712 unsplice(pred, s); |
713 return e; |
713 return e; |
784 private E firstDataItem() { |
784 private E firstDataItem() { |
785 for (Node p = head; p != null; p = succ(p)) { |
785 for (Node p = head; p != null; p = succ(p)) { |
786 Object item = p.item; |
786 Object item = p.item; |
787 if (p.isData) { |
787 if (p.isData) { |
788 if (item != null && item != p) |
788 if (item != null && item != p) |
789 return this.<E>cast(item); |
789 return LinkedTransferQueue.<E>cast(item); |
790 } |
790 } |
791 else if (item == null) |
791 else if (item == null) |
792 return null; |
792 return null; |
793 } |
793 } |
794 return null; |
794 return null; |
1043 * Inserts the specified element at the tail of this queue. |
1042 * Inserts the specified element at the tail of this queue. |
1044 * As the queue is unbounded, this method will never block or |
1043 * As the queue is unbounded, this method will never block or |
1045 * return {@code false}. |
1044 * return {@code false}. |
1046 * |
1045 * |
1047 * @return {@code true} (as specified by |
1046 * @return {@code true} (as specified by |
1048 * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer}) |
1047 * {@link java.util.concurrent.BlockingQueue#offer(Object,long,TimeUnit) |
|
1048 * BlockingQueue.offer}) |
1049 * @throws NullPointerException if the specified element is null |
1049 * @throws NullPointerException if the specified element is null |
1050 */ |
1050 */ |
1051 public boolean offer(E e, long timeout, TimeUnit unit) { |
1051 public boolean offer(E e, long timeout, TimeUnit unit) { |
1052 xfer(e, true, ASYNC, 0); |
1052 xfer(e, true, ASYNC, 0); |
1053 return true; |
1053 return true; |
1286 /** |
1284 /** |
1287 * Always returns {@code Integer.MAX_VALUE} because a |
1285 * Always returns {@code Integer.MAX_VALUE} because a |
1288 * {@code LinkedTransferQueue} is not capacity constrained. |
1286 * {@code LinkedTransferQueue} is not capacity constrained. |
1289 * |
1287 * |
1290 * @return {@code Integer.MAX_VALUE} (as specified by |
1288 * @return {@code Integer.MAX_VALUE} (as specified by |
1291 * {@link BlockingQueue#remainingCapacity()}) |
1289 * {@link java.util.concurrent.BlockingQueue#remainingCapacity() |
|
1290 * BlockingQueue.remainingCapacity}) |
1292 */ |
1291 */ |
1293 public int remainingCapacity() { |
1292 public int remainingCapacity() { |
1294 return Integer.MAX_VALUE; |
1293 return Integer.MAX_VALUE; |
1295 } |
1294 } |
1296 |
1295 |
1318 */ |
1317 */ |
1319 private void readObject(java.io.ObjectInputStream s) |
1318 private void readObject(java.io.ObjectInputStream s) |
1320 throws java.io.IOException, ClassNotFoundException { |
1319 throws java.io.IOException, ClassNotFoundException { |
1321 s.defaultReadObject(); |
1320 s.defaultReadObject(); |
1322 for (;;) { |
1321 for (;;) { |
1323 @SuppressWarnings("unchecked") E item = (E) s.readObject(); |
1322 @SuppressWarnings("unchecked") |
|
1323 E item = (E) s.readObject(); |
1324 if (item == null) |
1324 if (item == null) |
1325 break; |
1325 break; |
1326 else |
1326 else |
1327 offer(item); |
1327 offer(item); |
1328 } |
1328 } |
1335 private static final long tailOffset; |
1335 private static final long tailOffset; |
1336 private static final long sweepVotesOffset; |
1336 private static final long sweepVotesOffset; |
1337 static { |
1337 static { |
1338 try { |
1338 try { |
1339 UNSAFE = sun.misc.Unsafe.getUnsafe(); |
1339 UNSAFE = sun.misc.Unsafe.getUnsafe(); |
1340 Class k = LinkedTransferQueue.class; |
1340 Class<?> k = LinkedTransferQueue.class; |
1341 headOffset = UNSAFE.objectFieldOffset |
1341 headOffset = UNSAFE.objectFieldOffset |
1342 (k.getDeclaredField("head")); |
1342 (k.getDeclaredField("head")); |
1343 tailOffset = UNSAFE.objectFieldOffset |
1343 tailOffset = UNSAFE.objectFieldOffset |
1344 (k.getDeclaredField("tail")); |
1344 (k.getDeclaredField("tail")); |
1345 sweepVotesOffset = UNSAFE.objectFieldOffset |
1345 sweepVotesOffset = UNSAFE.objectFieldOffset |