< prev index next >

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

Print this page
rev 15228 : [mq]: per_review


 127             // get into trouble later in the run loop if there's
 128             // memory shortage while loading/initializing it lazily.
 129             ensureClassInitialized(Cleaner.class);
 130         }
 131 
 132         ReferenceHandler(ThreadGroup g, String name) {
 133             super(g, null, name, 0, false);
 134         }
 135 
 136         public void run() {
 137             while (true) {
 138                 processPendingReferences();
 139             }
 140         }
 141     }
 142 
 143     /* Atomically get and clear (set to null) the VM's pending list.
 144      */
 145     private static native Reference<Object> getAndClearReferencePendingList();
 146 
 147     /* Atomically test whether the VM's pending list contains any
 148      * entries.  If not, and await is true, then block until the
 149      * pending list becomes non-empty.  The GC adds references to the
 150      * pending list and notifies waiting threads when references are
 151      * added.  Returns true when the pending list was found to be
 152      * non-empty.
 153      */
 154     private static native boolean checkReferencePendingList(boolean await);




 155 
 156     private static final Object processPendingLock = new Object();
 157     private static boolean processPendingActive = false;
 158 
 159     private static void processPendingReferences() {
 160         checkReferencePendingList(true);
 161         Reference<Object> pendingList;
 162         synchronized (processPendingLock) {
 163             pendingList = getAndClearReferencePendingList();
 164             processPendingActive = true;
 165         }
 166         while (pendingList != null) {
 167             Reference<Object> ref = pendingList;
 168             pendingList = ref.discovered;
 169             ref.discovered = null;
 170 
 171             if (ref instanceof Cleaner) {
 172                 ((Cleaner)ref).clean();
 173                 // Notify any waiters that progress has been made.
 174                 // This improves latency for nio.Bits waiters, which
 175                 // are the only important ones.
 176                 synchronized (processPendingLock) {
 177                     processPendingLock.notifyAll();
 178                 }
 179             } else {
 180                 ReferenceQueue<? super Object> q = ref.queue;


 182             }
 183         }
 184         // Notify any waiters of completion of current round.
 185         synchronized (processPendingLock) {
 186             processPendingActive = false;
 187             processPendingLock.notifyAll();
 188         }
 189     }
 190 
 191     /**
 192      * Wait for progress in {@link Reference} processing.  If there
 193      * aren't any pending {@link Reference}s, return immediately.
 194      *
 195      * @return {@code true} if there were any pending {@link Reference}s,
 196      * {@code false} otherwise.
 197      */
 198     private static boolean waitForReferenceProcessing()
 199         throws InterruptedException
 200     {
 201         synchronized (processPendingLock) {
 202             if (processPendingActive || checkReferencePendingList(false)) {
 203                 // Wait for progress, not necessarily completion.
 204                 processPendingLock.wait();
 205                 return true;
 206             } else {
 207                 return false;
 208             }
 209         }
 210     }
 211 
 212     static {
 213         ThreadGroup tg = Thread.currentThread().getThreadGroup();
 214         for (ThreadGroup tgn = tg;
 215              tgn != null;
 216              tg = tgn, tgn = tg.getParent());
 217         Thread handler = new ReferenceHandler(tg, "Reference Handler");
 218         /* If there were a special system-only priority greater than
 219          * MAX_PRIORITY, it would be used here
 220          */
 221         handler.setPriority(Thread.MAX_PRIORITY);
 222         handler.setDaemon(true);




 127             // get into trouble later in the run loop if there's
 128             // memory shortage while loading/initializing it lazily.
 129             ensureClassInitialized(Cleaner.class);
 130         }
 131 
 132         ReferenceHandler(ThreadGroup g, String name) {
 133             super(g, null, name, 0, false);
 134         }
 135 
 136         public void run() {
 137             while (true) {
 138                 processPendingReferences();
 139             }
 140         }
 141     }
 142 
 143     /* Atomically get and clear (set to null) the VM's pending list.
 144      */
 145     private static native Reference<Object> getAndClearReferencePendingList();
 146 
 147     /* Test whether the VM's pending list contains any entries.





 148      */
 149     private static native boolean hasReferencePendingList();
 150 
 151     /* Wait until the VM's pending list may be non-null.
 152      */
 153     private static native void waitForReferencePendingList();
 154 
 155     private static final Object processPendingLock = new Object();
 156     private static boolean processPendingActive = false;
 157 
 158     private static void processPendingReferences() {
 159         waitForReferencePendingList();
 160         Reference<Object> pendingList;
 161         synchronized (processPendingLock) {
 162             pendingList = getAndClearReferencePendingList();
 163             processPendingActive = true;
 164         }
 165         while (pendingList != null) {
 166             Reference<Object> ref = pendingList;
 167             pendingList = ref.discovered;
 168             ref.discovered = null;
 169 
 170             if (ref instanceof Cleaner) {
 171                 ((Cleaner)ref).clean();
 172                 // Notify any waiters that progress has been made.
 173                 // This improves latency for nio.Bits waiters, which
 174                 // are the only important ones.
 175                 synchronized (processPendingLock) {
 176                     processPendingLock.notifyAll();
 177                 }
 178             } else {
 179                 ReferenceQueue<? super Object> q = ref.queue;


 181             }
 182         }
 183         // Notify any waiters of completion of current round.
 184         synchronized (processPendingLock) {
 185             processPendingActive = false;
 186             processPendingLock.notifyAll();
 187         }
 188     }
 189 
 190     /**
 191      * Wait for progress in {@link Reference} processing.  If there
 192      * aren't any pending {@link Reference}s, return immediately.
 193      *
 194      * @return {@code true} if there were any pending {@link Reference}s,
 195      * {@code false} otherwise.
 196      */
 197     private static boolean waitForReferenceProcessing()
 198         throws InterruptedException
 199     {
 200         synchronized (processPendingLock) {
 201             if (processPendingActive || hasReferencePendingList()) {
 202                 // Wait for progress, not necessarily completion.
 203                 processPendingLock.wait();
 204                 return true;
 205             } else {
 206                 return false;
 207             }
 208         }
 209     }
 210 
 211     static {
 212         ThreadGroup tg = Thread.currentThread().getThreadGroup();
 213         for (ThreadGroup tgn = tg;
 214              tgn != null;
 215              tg = tgn, tgn = tg.getParent());
 216         Thread handler = new ReferenceHandler(tg, "Reference Handler");
 217         /* If there were a special system-only priority greater than
 218          * MAX_PRIORITY, it would be used here
 219          */
 220         handler.setPriority(Thread.MAX_PRIORITY);
 221         handler.setDaemon(true);


< prev index next >