1 7 8 package java.lang.ref; 9 10 import sun.misc.Cleaner; 11 12 13 23 24 public abstract class Reference<T> { 25 26 72 73 private T referent; 74 75 ReferenceQueue <? super T> queue; 76 77 Reference next; 78 transient private Reference <T> discovered; 79 80 81 86 static private class Lock { }; 87 private static Lock lock = new Lock(); 88 89 90 94 private static Reference pending = null; 95 96 98 private static class ReferenceHandler extends Thread { 99 100 ReferenceHandler(ThreadGroup g, String name) { 101 super(g, name); 102 } 103 104 public void run() { 105 for (;;) { 106 107 Reference r; 108 synchronized (lock) { 109 if (pending != null) { 110 r = pending; 111 Reference rn = r.next; 112 pending = (rn == r) ? null : rn; 113 r.next = r; 114 } else { 115 try { 116 lock.wait(); 117 } catch (InterruptedException x) { } 118 continue; 119 } 120 } 121 122 if (r instanceof Cleaner) { 124 ((Cleaner)r).clean(); 125 continue; 126 } 127 128 ReferenceQueue q = r.queue; 129 if (q != ReferenceQueue.NULL) q.enqueue(r); 130 } 131 } 132 } 133 134 static { 135 ThreadGroup tg = Thread.currentThread().getThreadGroup(); 136 for (ThreadGroup tgn = tg; 137 tgn != null; 138 tg = tgn, tgn = tg.getParent()); 139 Thread handler = new ReferenceHandler(tg, "Reference Handler"); 140 143 handler.setPriority(Thread.MAX_PRIORITY); 144 handler.setDaemon(true); 145 handler.start(); 146 } 147 148 149 150 151 159 public T get() { 160 return this.referent; 161 } 162 163 167 public void clear() { 168 this.referent = null; 169 } 170 171 172 173 174 183 public boolean isEnqueued() { 184 186 synchronized (this) { 187 return (this.queue != ReferenceQueue.NULL) && (this.next != null); 188 } 189 } 190 191 199 public boolean enqueue() { 200 return this.queue.enqueue(this); 201 } 202 203 204 205 206 Reference(T referent) { 207 this(referent, null); 208 } 209 210 Reference(T referent, ReferenceQueue <? super T> queue) { 211 this.referent = referent; 212 this.queue = (queue == null) ? ReferenceQueue.NULL : queue; 213 } 214 215 } 216 | Popular Tags |