ReferenceQueue.java revision f5597e626ecf7949d249dea08c1a2964d890ec11
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note
19f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// This implementation is quite different from Harmony. Changes are not marked.
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note
21f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.lang.ref;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code ReferenceQueue} is the container on which reference objects are
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * enqueued when the garbage collector detects the reachability type specified
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the referent.
28f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
29f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.2
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ReferenceQueue<T> {
32f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Reference<? extends T> head;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of this class.
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ReferenceQueue() {
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super();
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the next available reference from the queue, removing it in the
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * process. Does not wait for a reference to become available.
45f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the next available reference, or {@code null} if no reference is
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         immediately available
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Reference<? extends T> poll() {
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (head == null) {
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reference<? extends T> ret;
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ret = head;
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (head == head.queueNext) {
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            head = null;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            head = head.queueNext;
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ret.queueNext = null;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ret;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the next available reference from the queue, removing it in the
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * process. Waits indefinitely for a reference to become available.
73f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the next available reference
75f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InterruptedException
77f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if the blocking call was interrupted for some reason
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Reference<? extends T> remove() throws InterruptedException {
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return remove(0L);
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
82f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the next available reference from the queue, removing it in the
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * process. Waits for a reference to become available or the given timeout
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * period to elapse, whichever happens first.
87f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            maximum time (in ms) to spend waiting for a reference object
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            to become available. A value of zero results in the method
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            waiting indefinitely.
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the next available reference, or {@code null} if no reference
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         becomes available within the timeout period
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the wait period is negative.
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InterruptedException
97f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *             if the blocking call was interrupted for some reason
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized Reference<? extends T> remove(long timeout) throws IllegalArgumentException,
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InterruptedException {
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout == 0L) {
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (head == null) {
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                wait(0L);
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long now = System.currentTimeMillis();
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long wakeupTime = now + timeout + 1L;
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (head == null && now < wakeupTime) {
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                wait(wakeupTime - now);
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                now = System.currentTimeMillis();
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return poll();
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
122f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Enqueue the reference object on the receiver.
123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @param reference
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            reference object to be enqueued.
126f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @return boolean true if reference is enqueued. false if reference failed
127f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *         to enqueue.
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
129f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    synchronized void enqueue(Reference<? extends T> reference) {
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (head == null) {
131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            reference.queueNext = reference;
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
133f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            reference.queueNext = head;
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
135f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        head = reference;
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        notify();
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
139