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;
+ }
+ }
+ }
}