< prev index next >

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

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.ref;
  27 


  28 import java.lang.ref.Cleaner;
  29 import java.lang.ref.Cleaner.Cleanable;
  30 import java.lang.ref.ReferenceQueue;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedAction;
  33 import java.util.concurrent.ThreadFactory;
  34 import java.util.concurrent.atomic.AtomicInteger;

  35 import java.util.function.Function;
  36 
  37 import jdk.internal.misc.InnocuousThread;

  38 
  39 /**
  40  * CleanerImpl manages a set of object references and corresponding cleaning actions.
  41  * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
  42  */
  43 public final class CleanerImpl implements Runnable {
  44 
  45     /**
  46      * An object to access the CleanerImpl from a Cleaner; set by Cleaner init.
  47      */
  48     private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null;
  49 
  50     /**
  51      * Heads of a CleanableList for each reference type.
  52      */
  53     final PhantomCleanable<?> phantomCleanableList;
  54 
  55     final WeakCleanable<?> weakCleanableList;
  56 
  57     final SoftCleanable<?> softCleanableList;


 167          * @param obj the object to monitor
 168          * @param cleaner the cleaner
 169          * @param action the action Runnable
 170          */
 171         public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
 172             super(obj, cleaner);
 173             this.action = action;
 174         }
 175 
 176         /**
 177          * Constructor used only for root of phantom cleanable list.
 178          */
 179         PhantomCleanableRef() {
 180             super();
 181             this.action = null;
 182         }
 183 
 184         @Override
 185         protected void performCleanup() {
 186             action.run();





































































































































































 187         }
 188 
 189         /**
 190          * Prevent access to referent even when it is still alive.
 191          *
 192          * @throws UnsupportedOperationException always
 193          */
 194         @Override
 195         public Object get() {
 196             throw new UnsupportedOperationException("get");
 197         }
 198 
 199         /**
 200          * Direct clearing of the referent is not supported.
 201          *
 202          * @throws UnsupportedOperationException always
 203          */
 204         @Override
 205         public void clear() {
 206             throw new UnsupportedOperationException("clear");




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.internal.ref;
  27 
  28 import jdk.internal.misc.InnocuousThread;
  29 
  30 import java.lang.ref.Cleaner;
  31 import java.lang.ref.Cleaner.Cleanable;
  32 import java.lang.ref.ReferenceQueue;
  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import java.util.concurrent.ThreadFactory;
  36 import java.util.concurrent.atomic.AtomicInteger;
  37 import java.util.function.Consumer;
  38 import java.util.function.Function;
  39 import java.util.function.LongConsumer;
  40 import java.util.function.LongSupplier;
  41 import java.util.function.Supplier;
  42 
  43 /**
  44  * CleanerImpl manages a set of object references and corresponding cleaning actions.
  45  * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
  46  */
  47 public final class CleanerImpl implements Runnable {
  48 
  49     /**
  50      * An object to access the CleanerImpl from a Cleaner; set by Cleaner init.
  51      */
  52     private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null;
  53 
  54     /**
  55      * Heads of a CleanableList for each reference type.
  56      */
  57     final PhantomCleanable<?> phantomCleanableList;
  58 
  59     final WeakCleanable<?> weakCleanableList;
  60 
  61     final SoftCleanable<?> softCleanableList;


 171          * @param obj the object to monitor
 172          * @param cleaner the cleaner
 173          * @param action the action Runnable
 174          */
 175         public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
 176             super(obj, cleaner);
 177             this.action = action;
 178         }
 179 
 180         /**
 181          * Constructor used only for root of phantom cleanable list.
 182          */
 183         PhantomCleanableRef() {
 184             super();
 185             this.action = null;
 186         }
 187 
 188         @Override
 189         protected void performCleanup() {
 190             action.run();
 191         }
 192 
 193         /**
 194          * Prevent access to referent even when it is still alive.
 195          *
 196          * @throws UnsupportedOperationException always
 197          */
 198         @Override
 199         public Object get() {
 200             throw new UnsupportedOperationException("get");
 201         }
 202 
 203         /**
 204          * Direct clearing of the referent is not supported.
 205          *
 206          * @throws UnsupportedOperationException always
 207          */
 208         @Override
 209         public void clear() {
 210             throw new UnsupportedOperationException("clear");
 211         }
 212     }
 213 
 214     /**
 215      * Reference-valued resource, automatically cleaned when
 216      * the tracked referent becomes phantom-reachable.
 217      *
 218      * @param <T> the type of resource
 219      * @since 10
 220      */
 221     public static final class PhantomCleanableResource<T>
 222         extends PhantomCleanable<Object>
 223         implements Cleaner.CleanableResource<T> {
 224 
 225         private final T resource;
 226         private Consumer<? super T> deallocator;
 227 
 228         /**
 229          * Constructor for a phantom cleanable resource.
 230          * @param obj the object to monitor
 231          * @param cleaner the cleaner
 232          * @param allocator the resource allocator function
 233          * @param deallocator the resource de-allocator function
 234          */
 235         public PhantomCleanableResource(Object obj, Cleaner cleaner,
 236                                         Supplier<? extends T> allocator,
 237                                         Consumer<? super T> deallocator) {
 238             super(obj, cleaner);
 239             try {
 240                 this.resource = allocator.get();
 241             } catch (Throwable t) {
 242                 // effectively de-register this cleanable in case
 243                 // resource allocation fails
 244                 super.clear();
 245                 throw t;
 246             }
 247             this.deallocator = deallocator;
 248         }
 249 
 250 
 251         @Override
 252         protected void performCleanup() {
 253             Consumer<? super T> deallocator = this.deallocator;
 254             // only when deallocator was assigned, we can be sure that
 255             // allocator.get() returned successfully
 256             if (deallocator != null) {
 257                 // mark that cleanup has been performed
 258                 this.deallocator = null;
 259                 deallocator.accept(resource);
 260             }
 261         }
 262 
 263         /**
 264          * Access to the allocated resource.
 265          *
 266          * @return the allocated resource
 267          */
 268         @Override
 269         public T value() {
 270             if (deallocator == null) {
 271                 throw new IllegalStateException("Already cleaned");
 272             }
 273             return resource;
 274         }
 275 
 276         /**
 277          * Prevent access to referent even when it is still alive.
 278          *
 279          * @throws UnsupportedOperationException always
 280          */
 281         @Override
 282         public Object get() {
 283             throw new UnsupportedOperationException("get");
 284         }
 285 
 286         /**
 287          * Direct clearing of the referent is not supported.
 288          *
 289          * @throws UnsupportedOperationException always
 290          */
 291         @Override
 292         public void clear() {
 293             throw new UnsupportedOperationException("clear");
 294         }
 295     }
 296 
 297     /**
 298      * Long-valued resource, automatically cleaned when
 299      * the tracked referent becomes phantom-reachable.
 300      *
 301      * @since 10
 302      */
 303     public static final class PhantomLongCleanableResource
 304         extends PhantomCleanable<Object>
 305         implements Cleaner.LongCleanableResource {
 306 
 307         private final long resource;
 308         private LongConsumer deallocator;
 309 
 310         /**
 311          * Constructor for a phantom cleanable resource.
 312          * @param obj the object to monitor
 313          * @param cleaner the cleaner
 314          * @param allocator the resource allocator function
 315          * @param deallocator the resource de-allocator function
 316          */
 317         public PhantomLongCleanableResource(Object obj, Cleaner cleaner,
 318                                             LongSupplier allocator,
 319                                             LongConsumer deallocator) {
 320             super(obj, cleaner);
 321             try {
 322                 this.resource = allocator.getAsLong();
 323             } catch (Throwable t) {
 324                 // effectively de-register this cleanable in case
 325                 // resource allocation fails
 326                 super.clear();
 327                 throw t;
 328             }
 329             this.deallocator = deallocator;
 330         }
 331 
 332 
 333         @Override
 334         protected void performCleanup() {
 335             LongConsumer deallocator = this.deallocator;
 336             // only when deallocator was assigned, we can be sure that
 337             // allocator.get() returned successfully
 338             if (deallocator != null) {
 339                 // mark that cleanup has been performed
 340                 this.deallocator = null;
 341                 deallocator.accept(resource);
 342             }
 343         }
 344 
 345         /**
 346          * Access to the allocated resource.
 347          *
 348          * @return the allocated resource
 349          */
 350         @Override
 351         public long value() {
 352             if (deallocator == null) {
 353                 throw new IllegalStateException("Already cleaned");
 354             }
 355             return resource;
 356         }
 357 
 358         /**
 359          * Prevent access to referent even when it is still alive.
 360          *
 361          * @throws UnsupportedOperationException always
 362          */
 363         @Override
 364         public Object get() {
 365             throw new UnsupportedOperationException("get");
 366         }
 367 
 368         /**
 369          * Direct clearing of the referent is not supported.
 370          *
 371          * @throws UnsupportedOperationException always
 372          */
 373         @Override
 374         public void clear() {
 375             throw new UnsupportedOperationException("clear");


< prev index next >