jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java
changeset 11279 d9dab5ec5044
parent 9515 04056ec0f477
child 14325 622c473a21aa
equal deleted inserted replaced
11277:e3a1c90dd439 11279:d9dab5ec5044
   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;
  1006             }
  1006             }
  1007         }
  1007         }
  1008         return false;
  1008         return false;
  1009     }
  1009     }
  1010 
  1010 
  1011 
       
  1012     /**
  1011     /**
  1013      * Creates an initially empty {@code LinkedTransferQueue}.
  1012      * Creates an initially empty {@code LinkedTransferQueue}.
  1014      */
  1013      */
  1015     public LinkedTransferQueue() {
  1014     public LinkedTransferQueue() {
  1016     }
  1015     }
  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;
  1160         if (c == null)
  1160         if (c == null)
  1161             throw new NullPointerException();
  1161             throw new NullPointerException();
  1162         if (c == this)
  1162         if (c == this)
  1163             throw new IllegalArgumentException();
  1163             throw new IllegalArgumentException();
  1164         int n = 0;
  1164         int n = 0;
  1165         E e;
  1165         for (E e; (e = poll()) != null;) {
  1166         while ( (e = poll()) != null) {
       
  1167             c.add(e);
  1166             c.add(e);
  1168             ++n;
  1167             ++n;
  1169         }
  1168         }
  1170         return n;
  1169         return n;
  1171     }
  1170     }
  1178         if (c == null)
  1177         if (c == null)
  1179             throw new NullPointerException();
  1178             throw new NullPointerException();
  1180         if (c == this)
  1179         if (c == this)
  1181             throw new IllegalArgumentException();
  1180             throw new IllegalArgumentException();
  1182         int n = 0;
  1181         int n = 0;
  1183         E e;
  1182         for (E e; n < maxElements && (e = poll()) != null;) {
  1184         while (n < maxElements && (e = poll()) != null) {
       
  1185             c.add(e);
  1183             c.add(e);
  1186             ++n;
  1184             ++n;
  1187         }
  1185         }
  1188         return n;
  1186         return n;
  1189     }
  1187     }
  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