26 package java.lang.ref;
27
28 import java.util.function.Consumer;
29 import jdk.internal.misc.VM;
30
31 /**
32 * Reference queues, to which registered reference objects are appended by the
33 * garbage collector after the appropriate reachability changes are detected.
34 *
35 * @author Mark Reinhold
36 * @since 1.2
37 */
38
39 public class ReferenceQueue<T> {
40
41 /**
42 * Constructs a new reference-object queue.
43 */
44 public ReferenceQueue() { }
45
46 private static class Null<S> extends ReferenceQueue<S> {
47 boolean enqueue(Reference<? extends S> r) {
48 return false;
49 }
50 }
51
52 static ReferenceQueue<Object> NULL = new Null<>();
53 static ReferenceQueue<Object> ENQUEUED = new Null<>();
54
55 private static class Lock { };
56 private Lock lock = new Lock();
57 private volatile Reference<? extends T> head;
58 private long queueLength = 0;
59
60 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
61 synchronized (lock) {
62 // Check that since getting the lock this reference hasn't already been
63 // enqueued (and even then removed)
64 ReferenceQueue<?> queue = r.queue;
65 if ((queue == NULL) || (queue == ENQUEUED)) {
66 return false;
67 }
68 assert queue == this;
69 r.next = (head == null) ? r : head;
70 head = r;
71 queueLength++;
72 // Update r.queue *after* adding to list, to avoid race
73 // with concurrent enqueued checks and fast-path poll().
74 // Volatiles ensure ordering.
75 r.queue = ENQUEUED;
76 if (r instanceof FinalReference) {
|
26 package java.lang.ref;
27
28 import java.util.function.Consumer;
29 import jdk.internal.misc.VM;
30
31 /**
32 * Reference queues, to which registered reference objects are appended by the
33 * garbage collector after the appropriate reachability changes are detected.
34 *
35 * @author Mark Reinhold
36 * @since 1.2
37 */
38
39 public class ReferenceQueue<T> {
40
41 /**
42 * Constructs a new reference-object queue.
43 */
44 public ReferenceQueue() { }
45
46 private static class Null extends ReferenceQueue<Object> {
47 boolean enqueue(Reference<?> r) {
48 return false;
49 }
50 }
51
52 static final ReferenceQueue<Object> NULL = new Null();
53 static final ReferenceQueue<Object> ENQUEUED = new Null();
54
55 private static class Lock { };
56 private final Lock lock = new Lock();
57 private volatile Reference<? extends T> head;
58 private long queueLength = 0;
59
60 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
61 synchronized (lock) {
62 // Check that since getting the lock this reference hasn't already been
63 // enqueued (and even then removed)
64 ReferenceQueue<?> queue = r.queue;
65 if ((queue == NULL) || (queue == ENQUEUED)) {
66 return false;
67 }
68 assert queue == this;
69 r.next = (head == null) ? r : head;
70 head = r;
71 queueLength++;
72 // Update r.queue *after* adding to list, to avoid race
73 // with concurrent enqueued checks and fast-path poll().
74 // Volatiles ensure ordering.
75 r.queue = ENQUEUED;
76 if (r instanceof FinalReference) {
|