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

Print this page

        

*** 24,33 **** --- 24,35 ---- */ package java.lang.ref; import sun.misc.Cleaner; + import sun.misc.JavaLangRefAccess; + import sun.misc.SharedSecrets; /** * Abstract base class for reference objects. This class defines the * operations common to all reference objects. Because reference objects are * implemented in close cooperation with the garbage collector, this class may
*** 145,155 **** ReferenceHandler(ThreadGroup g, String name) { super(g, name); } public void run() { ! for (;;) { Reference<Object> r; Cleaner c; try { synchronized (lock) { if (pending != null) { --- 147,179 ---- ReferenceHandler(ThreadGroup g, String name) { super(g, name); } public void run() { ! while (true) { ! tryHandlePending(true); ! } ! } ! } ! ! /** ! * Try handle pending {@link Reference} if there is one.<p> ! * Return {@code true} as a hint that there might be another ! * {@link Reference} pending or {@code false} when there are no more pending ! * {@link Reference}s at the moment and the program can do some other ! * useful work instead of looping. ! * ! * @param waitForNotify if {@code true} and there was no pending ! * {@link Reference}, wait until notified from VM ! * or interrupted; if {@code false}, return immediately ! * when there is no pending {@link Reference}. ! * @return {@code true} if there was a {@link Reference} pending and it ! * was processed, or we waited for notification and either got it ! * or thread was interrupted before being notified; ! * {@code false} otherwise. ! */ ! static boolean tryHandlePending(boolean waitForNotify) { Reference<Object> r; Cleaner c; try { synchronized (lock) { if (pending != null) {
*** 161,197 **** pending = r.discovered; r.discovered = null; } else { // The waiting on the lock may cause an OutOfMemoryError // because it may try to allocate exception objects. lock.wait(); ! continue; } } } catch (OutOfMemoryError x) { // Give other threads CPU time so they hopefully drop some live references // and GC reclaims some space. // Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above // persistently throws OOME for some time... Thread.yield(); // retry ! continue; } catch (InterruptedException x) { // retry ! continue; } // Fast path for cleaners if (c != null) { c.clean(); ! continue; } ! ReferenceQueue<Object> q = r.queue; if (q != ReferenceQueue.NULL) q.enqueue(r); ! } ! } } static { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tgn = tg; --- 185,223 ---- pending = r.discovered; r.discovered = null; } else { // The waiting on the lock may cause an OutOfMemoryError // because it may try to allocate exception objects. + if (waitForNotify) { lock.wait(); ! } ! // retry if waited ! return waitForNotify; } } } catch (OutOfMemoryError x) { // Give other threads CPU time so they hopefully drop some live references // and GC reclaims some space. // Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above // persistently throws OOME for some time... Thread.yield(); // retry ! return true; } catch (InterruptedException x) { // retry ! return true; } // Fast path for cleaners if (c != null) { c.clean(); ! return true; } ! ReferenceQueue<? super Object> q = r.queue; if (q != ReferenceQueue.NULL) q.enqueue(r); ! return true; } static { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tgn = tg;
*** 202,213 **** * MAX_PRIORITY, it would be used here */ handler.setPriority(Thread.MAX_PRIORITY); handler.setDaemon(true); handler.start(); - } /* -- Referent accessor and setters -- */ /** * Returns this reference object's referent. If this reference object has --- 228,246 ---- * MAX_PRIORITY, it would be used here */ handler.setPriority(Thread.MAX_PRIORITY); handler.setDaemon(true); handler.start(); + // provide access in SharedSecrets + SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() { + @Override + public boolean tryHandlePendingReference() { + return tryHandlePending(false); + } + }); + } /* -- Referent accessor and setters -- */ /** * Returns this reference object's referent. If this reference object has