< prev index next >

src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java

Print this page




  59     final ReferenceQueue<Object> queue;
  60 
  61     /**
  62      * Called by Cleaner static initialization to provide the function
  63      * to map from Cleaner to CleanerImpl.
  64      * @param access a function to map from Cleaner to CleanerImpl
  65      */
  66     public static void setCleanerImplAccess(Function<Cleaner, CleanerImpl> access) {
  67         if (cleanerImplAccess == null) {
  68             cleanerImplAccess = access;
  69         } else {
  70             throw new InternalError("cleanerImplAccess");
  71         }
  72     }
  73 
  74     /**
  75      * Called to get the CleanerImpl for a Cleaner.
  76      * @param cleaner the cleaner
  77      * @return the corresponding CleanerImpl
  78      */
  79     static CleanerImpl getCleanerImpl(Cleaner cleaner) {
  80         return cleanerImplAccess.apply(cleaner);
  81     }
  82 
  83     /**
  84      * Constructor for CleanerImpl.
  85      */
  86     public CleanerImpl() {
  87         queue = new ReferenceQueue<>();
  88         phantomCleanableList = new PhantomCleanableRef();
  89         weakCleanableList = new WeakCleanableRef();
  90         softCleanableList = new SoftCleanableRef();
  91     }
  92 
  93     /**
  94      * Starts the Cleaner implementation.
  95      * Ensure this is the CleanerImpl for the Cleaner.
  96      * When started waits for Cleanables to be queued.
  97      * @param cleaner the cleaner
  98      * @param threadFactory the thread factory
  99      */


 130      */
 131     private void run() {
 132         Thread t = Thread.currentThread();
 133         InnocuousThread mlThread = (t instanceof InnocuousThread)
 134                 ? (InnocuousThread) t
 135                 : null;
 136         while (!phantomCleanableList.isListEmpty() ||
 137                 !weakCleanableList.isListEmpty() ||
 138                 !softCleanableList.isListEmpty()) {
 139             if (mlThread != null) {
 140                 // Clear the thread locals
 141                 mlThread.eraseThreadLocals();
 142             }
 143             try {
 144                 // Wait for a Ref, with a timeout to avoid getting hung
 145                 // due to a race with clear/clean
 146                 Cleanable ref = (Cleanable) queue.remove(60 * 1000L);
 147                 if (ref != null) {
 148                     ref.clean();
 149                 }
 150             } catch (InterruptedException i) {
 151                 continue;   // ignore the interruption
 152             } catch (Throwable e) {
 153                 // ignore exceptions from the cleanup action

 154             }
 155         }




















 156     }
 157 
 158     /**
 159      * Perform cleaning on an unreachable PhantomReference.
 160      */
 161     public static final class PhantomCleanableRef extends PhantomCleanable<Object> {
 162         private final Runnable action;
 163 
 164         /**
 165          * Constructor for a phantom cleanable reference.
 166          * @param obj the object to monitor
 167          * @param cleaner the cleaner
 168          * @param action the action Runnable
 169          */
 170         public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
 171             super(obj, cleaner);
 172             this.action = action;
 173         }
 174 
 175         /**




  59     final ReferenceQueue<Object> queue;
  60 
  61     /**
  62      * Called by Cleaner static initialization to provide the function
  63      * to map from Cleaner to CleanerImpl.
  64      * @param access a function to map from Cleaner to CleanerImpl
  65      */
  66     public static void setCleanerImplAccess(Function<Cleaner, CleanerImpl> access) {
  67         if (cleanerImplAccess == null) {
  68             cleanerImplAccess = access;
  69         } else {
  70             throw new InternalError("cleanerImplAccess");
  71         }
  72     }
  73 
  74     /**
  75      * Called to get the CleanerImpl for a Cleaner.
  76      * @param cleaner the cleaner
  77      * @return the corresponding CleanerImpl
  78      */
  79     public static CleanerImpl getCleanerImpl(Cleaner cleaner) {
  80         return cleanerImplAccess.apply(cleaner);
  81     }
  82 
  83     /**
  84      * Constructor for CleanerImpl.
  85      */
  86     public CleanerImpl() {
  87         queue = new ReferenceQueue<>();
  88         phantomCleanableList = new PhantomCleanableRef();
  89         weakCleanableList = new WeakCleanableRef();
  90         softCleanableList = new SoftCleanableRef();
  91     }
  92 
  93     /**
  94      * Starts the Cleaner implementation.
  95      * Ensure this is the CleanerImpl for the Cleaner.
  96      * When started waits for Cleanables to be queued.
  97      * @param cleaner the cleaner
  98      * @param threadFactory the thread factory
  99      */


 130      */
 131     private void run() {
 132         Thread t = Thread.currentThread();
 133         InnocuousThread mlThread = (t instanceof InnocuousThread)
 134                 ? (InnocuousThread) t
 135                 : null;
 136         while (!phantomCleanableList.isListEmpty() ||
 137                 !weakCleanableList.isListEmpty() ||
 138                 !softCleanableList.isListEmpty()) {
 139             if (mlThread != null) {
 140                 // Clear the thread locals
 141                 mlThread.eraseThreadLocals();
 142             }
 143             try {
 144                 // Wait for a Ref, with a timeout to avoid getting hung
 145                 // due to a race with clear/clean
 146                 Cleanable ref = (Cleanable) queue.remove(60 * 1000L);
 147                 if (ref != null) {
 148                     ref.clean();
 149                 }


 150             } catch (Throwable e) {
 151                 // ignore exceptions from the cleanup action
 152                 // (including interruption of cleanup thread)
 153             }
 154         }
 155     }
 156 
 157     /**
 158      * Processes all Cleanable(s) that have been waiting in the queue.
 159      *
 160      * @return {@code true} if any Cleanable was found in the queue and
 161      * was processed or {@code false} if the queue was empty.
 162      */
 163     public boolean drainQueue() {
 164         boolean cleaned = false;
 165         Cleanable ref;
 166         while ((ref = (Cleanable) queue.poll()) != null) {
 167             try {
 168                 ref.clean();
 169             } catch (Throwable t) {
 170                 // ignore exceptions from the cleanup action
 171             }
 172             cleaned = true;
 173         }
 174         return cleaned;
 175     }
 176 
 177     /**
 178      * Perform cleaning on an unreachable PhantomReference.
 179      */
 180     public static final class PhantomCleanableRef extends PhantomCleanable<Object> {
 181         private final Runnable action;
 182 
 183         /**
 184          * Constructor for a phantom cleanable reference.
 185          * @param obj the object to monitor
 186          * @param cleaner the cleaner
 187          * @param action the action Runnable
 188          */
 189         public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
 190             super(obj, cleaner);
 191             this.action = action;
 192         }
 193 
 194         /**


< prev index next >