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

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 23,32 **** --- 23,34 ---- * questions. */ package java.lang.ref; + import java.util.function.Consumer; + /** * Reference queues, to which registered reference objects are appended by the * garbage collector after the appropriate reachability changes are detected. * * @author Mark Reinhold
*** 73,89 **** lock.notifyAll(); return true; } } ! @SuppressWarnings("unchecked") private Reference<? extends T> reallyPoll() { /* Must hold lock */ Reference<? extends T> r = head; if (r != null) { ! head = (r.next == r) ? null : ! r.next; // Unchecked due to the next field having a raw type in Reference r.queue = NULL; r.next = r; queueLength--; if (r instanceof FinalReference) { sun.misc.VM.addFinalRefCount(-1); --- 75,92 ---- lock.notifyAll(); return true; } } ! @SuppressWarnings({"unchecked","rawtypes"}) private Reference<? extends T> reallyPoll() { /* Must hold lock */ Reference<? extends T> r = head; if (r != null) { ! Reference rn = r.next; ! head = (rn == r) ? null : ! rn; // Unchecked due to the next field having a raw type in Reference r.queue = NULL; r.next = r; queueLength--; if (r instanceof FinalReference) { sun.misc.VM.addFinalRefCount(-1);
*** 162,167 **** --- 165,198 ---- */ public Reference<? extends T> remove() throws InterruptedException { return remove(0); } + /** + * Iterate queue and invoke given action with each Reference. + * Suitable for diagnostic purposes. + * WARNING: any use of this method should make sure to not + * retain the referents of iterated references (in case of + * FinalReference(s)) so that their life is not prolonged more + * than necessary. + */ + @SuppressWarnings({"unchecked","rawtypes"}) + void forEach(Consumer<? super Reference<? extends T>> action) { + for (Reference<? extends T> r = head; r != null;) { + action.accept(r); + Reference rn = r.next; + if (rn == r) { + if (r.queue == ENQUEUED) { + // still enqueued -> we reached end of chain + r = null; + } else { + // already dequeued: r.queue == NULL; -> + // restart from head when overtaken by queue poller(s) + r = head; + } + } else { + // next in chain + r = rn; + } + } + } }