1 7 8 package java.lang.ref; 9 10 18 19 public class ReferenceQueue<T> { 20 21 24 public ReferenceQueue() { } 25 26 private static class Null extends ReferenceQueue { 27 boolean enqueue(Reference r) { 28 return false; 29 } 30 } 31 32 static ReferenceQueue NULL = new Null(); 33 static ReferenceQueue ENQUEUED = new Null(); 34 35 static private class Lock { }; 36 private Lock lock = new Lock(); 37 private Reference <? extends T> head = null; 38 private long queueLength = 0; 39 private volatile boolean queueEmpty = true; 40 41 boolean enqueue(Reference <? extends T> r) { 42 synchronized (r) { 43 if (r.queue == ENQUEUED) return false; 44 synchronized (lock) { 45 r.queue = ENQUEUED; 46 r.next = (head == null) ? r : head; 47 head = r; 48 queueLength++; 49 if (queueEmpty) queueEmpty = false; 50 if (r instanceof FinalReference ) { 51 sun.misc.VM.addFinalRefCount(1); 52 } 53 lock.notifyAll(); 54 return true; 55 } 56 } 57 } 58 59 private Reference <? extends T> reallyPoll() { 60 if (head != null) { 61 Reference <? extends T> r = head; 62 head = (r.next == r) ? null : r.next; 63 r.queue = NULL; 64 r.next = r; 65 queueLength--; 66 if (queueLength <= 0) queueEmpty = true; 67 if (r instanceof FinalReference ) { 68 sun.misc.VM.addFinalRefCount(-1); 69 } 70 return r; 71 } 72 return null; 73 } 74 75 83 public Reference <? extends T> poll() { 84 if(queueEmpty) return null; 85 synchronized (lock) { 86 return reallyPoll(); 87 } 88 } 89 90 110 public Reference <? extends T> remove(long timeout) 111 throws IllegalArgumentException , InterruptedException 112 { 113 if (timeout < 0) { 114 throw new IllegalArgumentException ("Negative timeout value"); 115 } 116 synchronized (lock) { 117 Reference <? extends T> r = reallyPoll(); 118 if (r != null) return r; 119 for (;;) { 120 lock.wait(timeout); 121 r = reallyPoll(); 122 if (r != null) return r; 123 if (timeout != 0) return null; 124 } 125 } 126 } 127 128 135 public Reference <? extends T> remove() throws InterruptedException { 136 return remove(0); 137 } 138 139 } 140 | Popular Tags |