38 /** 39 * Constructs a new reference-object queue. 40 */ 41 public ReferenceQueue() { } 42 43 private static class Null extends ReferenceQueue { 44 boolean enqueue(Reference r) { 45 return false; 46 } 47 } 48 49 static ReferenceQueue NULL = new Null(); 50 static ReferenceQueue ENQUEUED = new Null(); 51 52 static private class Lock { }; 53 private Lock lock = new Lock(); 54 private volatile Reference<? extends T> head = null; 55 private long queueLength = 0; 56 57 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */ 58 synchronized (r) { 59 if (r.queue == ENQUEUED) return false; 60 synchronized (lock) { 61 r.queue = ENQUEUED; 62 r.next = (head == null) ? r : head; 63 head = r; 64 queueLength++; 65 if (r instanceof FinalReference) { 66 sun.misc.VM.addFinalRefCount(1); 67 } 68 lock.notifyAll(); 69 return true; 70 } 71 } 72 } 73 74 private Reference<? extends T> reallyPoll() { /* Must hold lock */ 75 if (head != null) { 76 Reference<? extends T> r = head; 77 head = (r.next == r) ? null : r.next; 78 r.queue = NULL; 79 r.next = r; 80 queueLength--; 81 if (r instanceof FinalReference) { 82 sun.misc.VM.addFinalRefCount(-1); 83 } 84 return r; 85 } 86 return null; 87 } 88 89 /** 90 * Polls this queue to see if a reference object is available. If one is 91 * available without further delay then it is removed from the queue and 92 * returned. Otherwise this method immediately returns <tt>null</tt>. 93 * 94 * @return A reference object, if one was immediately available, 95 * otherwise <code>null</code> 96 */ | 38 /** 39 * Constructs a new reference-object queue. 40 */ 41 public ReferenceQueue() { } 42 43 private static class Null extends ReferenceQueue { 44 boolean enqueue(Reference r) { 45 return false; 46 } 47 } 48 49 static ReferenceQueue NULL = new Null(); 50 static ReferenceQueue ENQUEUED = new Null(); 51 52 static private class Lock { }; 53 private Lock lock = new Lock(); 54 private volatile Reference<? extends T> head = null; 55 private long queueLength = 0; 56 57 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */ 58 synchronized (lock) { 59 // Check that since getting the lock this reference hasn't already been 60 // enqueued (and even then removed) 61 ReferenceQueue queue = r.queue; 62 if ((queue == NULL) || (queue == ENQUEUED)) { 63 return false; 64 } 65 assert queue == this; 66 r.queue = ENQUEUED; 67 r.next = (head == null) ? r : head; 68 head = r; 69 queueLength++; 70 if (r instanceof FinalReference) { 71 sun.misc.VM.addFinalRefCount(1); 72 } 73 lock.notifyAll(); 74 return true; 75 } 76 } 77 78 private Reference<? extends T> reallyPoll() { /* Must hold lock */ 79 Reference<? extends T> r = head; 80 if (r != null) { 81 head = (r.next == r) ? null : r.next; 82 r.queue = NULL; 83 r.next = r; 84 queueLength--; 85 if (r instanceof FinalReference) { 86 sun.misc.VM.addFinalRefCount(-1); 87 } 88 return r; 89 } 90 return null; 91 } 92 93 /** 94 * Polls this queue to see if a reference object is available. If one is 95 * available without further delay then it is removed from the queue and 96 * returned. Otherwise this method immediately returns <tt>null</tt>. 97 * 98 * @return A reference object, if one was immediately available, 99 * otherwise <code>null</code> 100 */ |