src/share/classes/java/lang/ref/ReferenceQueue.java

Print this page
rev 905 : imported patch ref


  34  */
  35 
  36 public class ReferenceQueue<T> {
  37 
  38     /**
  39      * Constructs a new reference-object queue.
  40      */
  41     public ReferenceQueue() { }
  42 
  43     private static class Null extends ReferenceQueue {
  44         boolean enqueue(Reference r) {
  45             return false;
  46         }
  47     }
  48 
  49     static ReferenceQueue NULL = new Null();
  50     static ReferenceQueue ENQUEUED = new Null();
  51 
  52     static private class Lock { };
  53     private Lock lock = new Lock();
  54     private Reference<? extends T> head = null;
  55     private long queueLength = 0;
  56 
  57     boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
  58         synchronized (r) {
  59             if (r.queue == ENQUEUED) return false;
  60             synchronized (lock) {
  61                 r.queue = ENQUEUED;
  62                 r.next = (head == null) ? r : head;
  63                 head = r;
  64                 queueLength++;
  65                 if (r instanceof FinalReference) {
  66                     sun.misc.VM.addFinalRefCount(1);
  67                 }
  68                 lock.notifyAll();
  69                 return true;
  70             }
  71         }
  72     }
  73 
  74     private Reference<? extends T> reallyPoll() {       /* Must hold lock */


  78             r.queue = NULL;
  79             r.next = r;
  80             queueLength--;
  81             if (r instanceof FinalReference) {
  82                 sun.misc.VM.addFinalRefCount(-1);
  83             }
  84             return r;
  85         }
  86         return null;
  87     }
  88 
  89     /**
  90      * Polls this queue to see if a reference object is available.  If one is
  91      * available without further delay then it is removed from the queue and
  92      * returned.  Otherwise this method immediately returns <tt>null</tt>.
  93      *
  94      * @return  A reference object, if one was immediately available,
  95      *          otherwise <code>null</code>
  96      */
  97     public Reference<? extends T> poll() {


  98         synchronized (lock) {
  99             return reallyPoll();
 100         }
 101     }
 102 
 103     /**
 104      * Removes the next reference object in this queue, blocking until either
 105      * one becomes available or the given timeout period expires.
 106      *
 107      * <p> This method does not offer real-time guarantees: It schedules the
 108      * timeout as if by invoking the {@link Object#wait(long)} method.
 109      *
 110      * @param  timeout  If positive, block for up to <code>timeout</code>
 111      *                  milliseconds while waiting for a reference to be
 112      *                  added to this queue.  If zero, block indefinitely.
 113      *
 114      * @return  A reference object, if one was available within the specified
 115      *          timeout period, otherwise <code>null</code>
 116      *
 117      * @throws  IllegalArgumentException




  34  */
  35 
  36 public class ReferenceQueue<T> {
  37 
  38     /**
  39      * Constructs a new reference-object queue.
  40      */
  41     public ReferenceQueue() { }
  42 
  43     private static class Null extends ReferenceQueue {
  44         boolean enqueue(Reference r) {
  45             return false;
  46         }
  47     }
  48 
  49     static ReferenceQueue NULL = new Null();
  50     static ReferenceQueue ENQUEUED = new Null();
  51 
  52     static private class Lock { };
  53     private Lock lock = new Lock();
  54     private volatile Reference<? extends T> head = null;
  55     private long queueLength = 0;
  56 
  57     boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
  58         synchronized (r) {
  59             if (r.queue == ENQUEUED) return false;
  60             synchronized (lock) {
  61                 r.queue = ENQUEUED;
  62                 r.next = (head == null) ? r : head;
  63                 head = r;
  64                 queueLength++;
  65                 if (r instanceof FinalReference) {
  66                     sun.misc.VM.addFinalRefCount(1);
  67                 }
  68                 lock.notifyAll();
  69                 return true;
  70             }
  71         }
  72     }
  73 
  74     private Reference<? extends T> reallyPoll() {       /* Must hold lock */


  78             r.queue = NULL;
  79             r.next = r;
  80             queueLength--;
  81             if (r instanceof FinalReference) {
  82                 sun.misc.VM.addFinalRefCount(-1);
  83             }
  84             return r;
  85         }
  86         return null;
  87     }
  88 
  89     /**
  90      * Polls this queue to see if a reference object is available.  If one is
  91      * available without further delay then it is removed from the queue and
  92      * returned.  Otherwise this method immediately returns <tt>null</tt>.
  93      *
  94      * @return  A reference object, if one was immediately available,
  95      *          otherwise <code>null</code>
  96      */
  97     public Reference<? extends T> poll() {
  98         if (head == null)
  99             return null;
 100         synchronized (lock) {
 101             return reallyPoll();
 102         }
 103     }
 104 
 105     /**
 106      * Removes the next reference object in this queue, blocking until either
 107      * one becomes available or the given timeout period expires.
 108      *
 109      * <p> This method does not offer real-time guarantees: It schedules the
 110      * timeout as if by invoking the {@link Object#wait(long)} method.
 111      *
 112      * @param  timeout  If positive, block for up to <code>timeout</code>
 113      *                  milliseconds while waiting for a reference to be
 114      *                  added to this queue.  If zero, block indefinitely.
 115      *
 116      * @return  A reference object, if one was available within the specified
 117      *          timeout period, otherwise <code>null</code>
 118      *
 119      * @throws  IllegalArgumentException