src/share/classes/java/lang/ref/Reference.java

Print this page




 115     private static Lock lock = new Lock();
 116 
 117 
 118     /* List of References waiting to be enqueued.  The collector adds
 119      * References to this list, while the Reference-handler thread removes
 120      * them.  This list is protected by the above lock object. The
 121      * list uses the discovered field to link its elements.
 122      */
 123     private static Reference<Object> pending = null;
 124 
 125     /* High-priority thread to enqueue pending References
 126      */
 127     private static class ReferenceHandler extends Thread {
 128 
 129         ReferenceHandler(ThreadGroup g, String name) {
 130             super(g, name);
 131         }
 132 
 133         public void run() {
 134             for (;;) {

 135                 Reference<Object> r;
 136                 synchronized (lock) {
 137                     if (pending != null) {
 138                         r = pending;
 139                         pending = r.discovered;
 140                         r.discovered = null;
 141                     } else {
 142                         // The waiting on the lock may cause an OOME because it may try to allocate
 143                         // exception objects, so also catch OOME here to avoid silent exit of the
 144                         // reference handler thread.
 145                         //
 146                         // Explicitly define the order of the two exceptions we catch here
 147                         // when waiting for the lock.
 148                         //
 149                         // We do not want to try to potentially load the InterruptedException class
 150                         // (which would be done if this was its first use, and InterruptedException
 151                         // were checked first) in this situation.
 152                         //
 153                         // This may lead to the VM not ever trying to load the InterruptedException
 154                         // class again.
 155                         try {
 156                             try {
 157                                 lock.wait();
 158                             } catch (OutOfMemoryError x) { }
 159                         } catch (InterruptedException x) { }
 160                         continue;
 161                     }
 162                 }
 163 
 164                 // Fast path for cleaners
 165                 if (r instanceof Cleaner) {
 166                     ((Cleaner)r).clean();
 167                     continue;
 168                 }
 169 
 170                 ReferenceQueue<Object> q = r.queue;
 171                 if (q != ReferenceQueue.NULL) q.enqueue(r);


 172             }
 173         }
 174     }
 175 
 176     static {
 177         ThreadGroup tg = Thread.currentThread().getThreadGroup();
 178         for (ThreadGroup tgn = tg;
 179              tgn != null;
 180              tg = tgn, tgn = tg.getParent());
 181         Thread handler = new ReferenceHandler(tg, "Reference Handler");
 182         /* If there were a special system-only priority greater than
 183          * MAX_PRIORITY, it would be used here
 184          */
 185         handler.setPriority(Thread.MAX_PRIORITY);
 186         handler.setDaemon(true);
 187         handler.start();
 188     }
 189 
 190 
 191     /* -- Referent accessor and setters -- */




 115     private static Lock lock = new Lock();
 116 
 117 
 118     /* List of References waiting to be enqueued.  The collector adds
 119      * References to this list, while the Reference-handler thread removes
 120      * them.  This list is protected by the above lock object. The
 121      * list uses the discovered field to link its elements.
 122      */
 123     private static Reference<Object> pending = null;
 124 
 125     /* High-priority thread to enqueue pending References
 126      */
 127     private static class ReferenceHandler extends Thread {
 128 
 129         ReferenceHandler(ThreadGroup g, String name) {
 130             super(g, name);
 131         }
 132 
 133         public void run() {
 134             for (;;) {
 135                 try {
 136                     Reference<Object> r;
 137                     synchronized (lock) {
 138                         if (pending != null) {
 139                             r = pending;
 140                             pending = r.discovered;
 141                             r.discovered = null;
 142                         } else {
 143                             // The waiting on the lock may cause an OOME because it may try to allocate
 144                             // exception objects, so also catch OOME here to avoid silent exit of the
 145                             // reference handler thread.
 146                             //
 147                             // Explicitly define the order of the two exceptions we catch here
 148                             // when waiting for the lock.
 149                             //
 150                             // We do not want to try to potentially load the InterruptedException class
 151                             // (which would be done if this was its first use, and InterruptedException
 152                             // were checked first) in this situation.
 153                             //
 154                             // This may lead to the VM not ever trying to load the InterruptedException
 155                             // class again.
 156                             try {
 157                                 try {
 158                                     lock.wait();
 159                                 } catch (OutOfMemoryError x) { }
 160                             } catch (InterruptedException x) { }
 161                             continue;
 162                         }
 163                     }
 164 
 165                     // Fast path for cleaners
 166                     if (r instanceof Cleaner) {
 167                         ((Cleaner)r).clean();
 168                         continue;
 169                     }
 170 
 171                     ReferenceQueue<Object> q = r.queue;
 172                     if (q != ReferenceQueue.NULL) q.enqueue(r);
 173 
 174                 } catch (OutOfMemoryError x) { }
 175             }
 176         }
 177     }
 178 
 179     static {
 180         ThreadGroup tg = Thread.currentThread().getThreadGroup();
 181         for (ThreadGroup tgn = tg;
 182              tgn != null;
 183              tg = tgn, tgn = tg.getParent());
 184         Thread handler = new ReferenceHandler(tg, "Reference Handler");
 185         /* If there were a special system-only priority greater than
 186          * MAX_PRIORITY, it would be used here
 187          */
 188         handler.setPriority(Thread.MAX_PRIORITY);
 189         handler.setDaemon(true);
 190         handler.start();
 191     }
 192 
 193 
 194     /* -- Referent accessor and setters -- */