rt/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 604 emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java@3fcc279c921b
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
     1 /*
     2  * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.lang.ref;
    27 
    28 /**
    29  * Reference queues, to which registered reference objects are appended by the
    30  * garbage collector after the appropriate reachability changes are detected.
    31  *
    32  * @author   Mark Reinhold
    33  * @since    1.2
    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                 lock.notifyAll();
    66                 return true;
    67             }
    68         }
    69     }
    70 
    71     private Reference<? extends T> reallyPoll() {       /* Must hold lock */
    72         if (head != null) {
    73             Reference<? extends T> r = head;
    74             head = (r.next == r) ? null : r.next;
    75             r.queue = NULL;
    76             r.next = r;
    77             queueLength--;
    78             return r;
    79         }
    80         return null;
    81     }
    82 
    83     /**
    84      * Polls this queue to see if a reference object is available.  If one is
    85      * available without further delay then it is removed from the queue and
    86      * returned.  Otherwise this method immediately returns <tt>null</tt>.
    87      *
    88      * @return  A reference object, if one was immediately available,
    89      *          otherwise <code>null</code>
    90      */
    91     public Reference<? extends T> poll() {
    92         if (head == null)
    93             return null;
    94         synchronized (lock) {
    95             return reallyPoll();
    96         }
    97     }
    98 
    99     /**
   100      * Removes the next reference object in this queue, blocking until either
   101      * one becomes available or the given timeout period expires.
   102      *
   103      * <p> This method does not offer real-time guarantees: It schedules the
   104      * timeout as if by invoking the {@link Object#wait(long)} method.
   105      *
   106      * @param  timeout  If positive, block for up to <code>timeout</code>
   107      *                  milliseconds while waiting for a reference to be
   108      *                  added to this queue.  If zero, block indefinitely.
   109      *
   110      * @return  A reference object, if one was available within the specified
   111      *          timeout period, otherwise <code>null</code>
   112      *
   113      * @throws  IllegalArgumentException
   114      *          If the value of the timeout argument is negative
   115      *
   116      * @throws  InterruptedException
   117      *          If the timeout wait is interrupted
   118      */
   119     public Reference<? extends T> remove(long timeout)
   120         throws IllegalArgumentException, InterruptedException
   121     {
   122         if (timeout < 0) {
   123             throw new IllegalArgumentException("Negative timeout value");
   124         }
   125         synchronized (lock) {
   126             Reference<? extends T> r = reallyPoll();
   127             if (r != null) return r;
   128             for (;;) {
   129                 lock.wait(timeout);
   130                 r = reallyPoll();
   131                 if (r != null) return r;
   132                 if (timeout != 0) return null;
   133             }
   134         }
   135     }
   136 
   137     /**
   138      * Removes the next reference object in this queue, blocking until one
   139      * becomes available.
   140      *
   141      * @return A reference object, blocking until one becomes available
   142      * @throws  InterruptedException  If the wait is interrupted
   143      */
   144     public Reference<? extends T> remove() throws InterruptedException {
   145         return remove(0);
   146     }
   147 
   148 }