Path: blob/master/jcl/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
12520 views
/*[INCLUDE-IF Sidecar16]*/1package java.lang.ref;23/*[IF Sidecar19-SE]4import jdk.internal.ref.Cleaner;5/*[ELSE]*/6import sun.misc.Cleaner;7/*[ENDIF]*/89/*******************************************************************************10* Copyright (c) 1998, 2017 IBM Corp. and others11*12* This program and the accompanying materials are made available under13* the terms of the Eclipse Public License 2.0 which accompanies this14* distribution and is available at https://www.eclipse.org/legal/epl-2.0/15* or the Apache License, Version 2.0 which accompanies this distribution and16* is available at https://www.apache.org/licenses/LICENSE-2.0.17*18* This Source Code may also be made available under the following19* Secondary Licenses when the conditions for such availability set20* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU21* General Public License, version 2 with the GNU Classpath22* Exception [1] and GNU General Public License, version 2 with the23* OpenJDK Assembly Exception [2].24*25* [1] https://www.gnu.org/software/classpath/license.html26* [2] http://openjdk.java.net/legal/assembly-exception.html27*28* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception29*******************************************************************************/3031/**32* ReferenceQueue is the container on which reference objects33* are enqueued when their reachability type is detected for34* the referent.35*36* @author OTI37* @version initial38* @since 1.239*/4041public class ReferenceQueue<T> extends Object {42private Reference[] references;43private int head, tail;44private boolean empty;4546static private final int DEFAULT_QUEUE_SIZE = 128;4748private static final Class reflectRefClass;4950private static final Class classNameLockRefClass;5152static {53/*[PR CMVC 114480] deadlock loading sun.misc.Cleaner */54// cause sun.misc.Cleaner to be loaded55Class cl = Cleaner.class;56/*[PR 125873] Improve reflection cache */57Class tmpClass = null;58try {59tmpClass = Class.forName("java.lang.Class$ReflectRef"); //$NON-NLS-1$60} catch (ClassNotFoundException e) {}61reflectRefClass = tmpClass;6263Class tmpClass2 = null;64try {65tmpClass2 = Class.forName("java.lang.ClassLoader$ClassNameLockRef"); //$NON-NLS-1$66} catch (ClassNotFoundException e) {}67classNameLockRefClass = tmpClass2;68}6970/**71* Returns the next available reference from the queue72* if one is enqueued, null otherwise. Does not wait73* for a reference to become available.74*75* @return Reference76* next available Reference or NULL.77*/78public Reference<? extends T> poll () {79Reference ref;8081/* Optimization to return immediately and not synchronize if there is nothing in the queue */82if(empty) {83return null;84}85synchronized(this) {86if(empty) {87return null;88}89ref = references[head];90/*[PR 115652] null References when removed */91references[head++] = null;92ref.dequeue();93if(head == references.length) {94head = 0;95}96if(head == tail) {97empty = true;98}99}100return ref;101}102103/**104* Return the next available enqueued reference on the queue, blocking105* indefinitely until one is available.106*107* @author OTI108* @version initial109*110* @return Reference111* a Reference object if one is available,112* null otherwise.113* @exception InterruptedException114* to interrupt the wait.115*/116public Reference<? extends T> remove() throws InterruptedException {117return remove(0L);118}119120/**121* Return the next available enqueued reference on the queue, blocking122* up to the time given until one is available. Return null if no123* reference became available.124*125* @author OTI126* @version initial127*128* @param timeout129* maximum time spent waiting for a reference object130* to become available.131* @return Reference132* a Reference object if one is available,133* null otherwise.134* @exception IllegalArgumentException135* if the wait period is negative.136* @exception InterruptedException137* to interrupt the wait.138*/139public Reference<? extends T> remove(long timeout) throws IllegalArgumentException, InterruptedException {140if (timeout < 0) throw new IllegalArgumentException();141142Reference ref;143synchronized(this) {144if(empty) {145wait(timeout);146if(empty) return null;147}148ref = references[head];149/*[PR 115652] null References when removed */150references[head++] = null;151ref.dequeue();152if(head == references.length) {153head = 0;154}155if(head == tail) {156empty = true;157} else {158notifyAll();159}160}161return ref;162}163164/**165* Enqueue the reference object on the receiver.166*167* @param reference168* reference object to be enqueued.169* @return boolean170* true if reference is enqueued.171* false if reference failed to enqueue.172*/173boolean enqueue (Reference reference) {174/*[PR CMVC 96472] deadlock loading sun.misc.Cleaner */175/*[PR 102259] call Cleaner.clean(), do not enqueue */176if (reference instanceof Cleaner) {177reference.dequeue();178((Cleaner)reference).clean();179return true;180}181/*[PR 125873] Improve reflection cache */182Class refClass = reference.getClass();183if (refClass == reflectRefClass184|| refClass == classNameLockRefClass185) {186reference.dequeue();187((Runnable)reference).run();188return true;189}190synchronized(this) {191/*[PR CMVC 181985] Perf: zWAS ftprint regressed 6% Java7 vs 626FP1 -ReferenceQueue */192if ( references == null) {193references = new Reference[DEFAULT_QUEUE_SIZE];194} else if(!empty && head == tail) {195/* Queue is full - grow */196int newQueueSize = (int)(references.length * 1.10);197Reference newQueue[] = new Reference[newQueueSize];198System.arraycopy(references, head, newQueue, 0, references.length - head);199if(tail > 0) {200System.arraycopy(references, 0, newQueue, references.length - head, tail);201}202head = 0;203tail = references.length;204references = newQueue;205}206references[tail++] = reference;207if(tail == references.length) {208tail = 0;209}210empty = false;211notifyAll();212}213return true;214}215216void forEach(java.util.function.Consumer<? super Reference<? extends T>> consumer) {217}218219/**220* Constructs a new instance of this class.221*/222public ReferenceQueue() {223head = 0;224tail = 0;225empty = true;226}227}228229230