ReferenceQueue.java revision 2680db46e43b69cc1c49429d371cd1c7512d6f2c
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 Projectpackage java.lang.ref; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code ReferenceQueue} is the container on which reference objects are 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * enqueued when the garbage collector detects the reachability type specified 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the referent. 24f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 25f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.2 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ReferenceQueue<T> { 28250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson private static final int NANOS_PER_MILLI = 1000000; 29f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Reference<? extends T> head; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of this class. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ReferenceQueue() { 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the next available reference from the queue, removing it in the 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * process. Does not wait for a reference to become available. 41f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the next available reference, or {@code null} if no reference is 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * immediately available 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unchecked") 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Reference<? extends T> poll() { 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (head == null) { 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Reference<? extends T> ret; 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ret = head; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (head == head.queueNext) { 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project head = null; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project head = head.queueNext; 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ret.queueNext = null; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ret; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the next available reference from the queue, removing it in the 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * process. Waits indefinitely for a reference to become available. 69f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 70250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * @throws InterruptedException if the blocking call was interrupted 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Reference<? extends T> remove() throws InterruptedException { 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return remove(0L); 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 75f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the next available reference from the queue, removing it in the 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * process. Waits for a reference to become available or the given timeout 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * period to elapse, whichever happens first. 80f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 81250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * @param timeoutMillis maximum time to spend waiting for a reference object 82250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * to become available. A value of {@code 0} results in the method 83250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * waiting indefinitely. 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the next available reference, or {@code null} if no reference 85250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * becomes available within the timeout period 86250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * @throws IllegalArgumentException if {@code timeoutMillis < 0}. 87250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson * @throws InterruptedException if the blocking call was interrupted 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 89250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson public synchronized Reference<? extends T> remove(long timeoutMillis) 90250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson throws InterruptedException { 91250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson if (timeoutMillis < 0) { 92250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson throw new IllegalArgumentException("timeout < 0: " + timeoutMillis); 93250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson } 94250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson 95250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson if (head != null) { 96250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson return poll(); 97250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson } 98250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson 99250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson // avoid overflow: if total > 292 years, just wait forever 100250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson if (timeoutMillis == 0 || (timeoutMillis > Long.MAX_VALUE / NANOS_PER_MILLI)) { 101250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson do { 102250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson wait(0); 103250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson } while (head == null); 104250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson return poll(); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson // guaranteed to not overflow 108250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson long nanosToWait = timeoutMillis * NANOS_PER_MILLI; 109250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson int timeoutNanos = 0; 110250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson 111250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson // wait until notified or the timeout has elapsed 112250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson long startTime = System.nanoTime(); 113250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson while (true) { 114250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson wait(timeoutMillis, timeoutNanos); 115250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson if (head != null) { 116250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson break; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 118250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson long nanosElapsed = System.nanoTime() - startTime; 119250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson long nanosRemaining = nanosToWait - nanosElapsed; 120250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson if (nanosRemaining <= 0) { 121250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson break; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson timeoutMillis = nanosRemaining / NANOS_PER_MILLI; 124250e0d89cc3f5d2fc03ed23961c774c02f825ffdJesse Wilson timeoutNanos = (int) (nanosRemaining - timeoutMillis * NANOS_PER_MILLI); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return poll(); 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Enqueue the reference object on the receiver. 131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 132f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @param reference 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reference object to be enqueued. 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 135f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson synchronized void enqueue(Reference<? extends T> reference) { 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (head == null) { 137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson reference.queueNext = reference; 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson reference.queueNext = head; 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson head = reference; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notify(); 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 14455d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro 14564c6c367497c7fcf88e7527022234043e4460758Jesse Wilson /** @hide */ 1462680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes public static Reference<?> unenqueued = null; 14755d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro 14855d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro static void add(Reference<?> list) { 14955d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro synchronized (ReferenceQueue.class) { 15055d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro if (unenqueued == null) { 15155d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro unenqueued = list; 15255d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro } else { 15355d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro Reference<?> next = unenqueued.pendingNext; 15455d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro unenqueued.pendingNext = list.pendingNext; 15555d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro list.pendingNext = next; 15655d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro } 15755d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro ReferenceQueue.class.notifyAll(); 15855d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro } 15955d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 161