模块 java.base

类 Cleaner

java.lang.Object
java.lang.ref.Cleaner

public final class Cleaner extends Object
Cleaner 管理一组对象引用和相应的清理操作。

清洁操作是 registered 在清洁器收到对象已变为幻象可达的通知后运行。清洁器使用 PhantomReference ReferenceQueue 可达性 更改时收到通知。

每个清洁器独立运行,管理待处理的清洁操作并在清洁器不再使用时处理线程和终止。注册一个对象引用和相应的清理操作返回一个 Cleanable 。最有效的用法是在对象关闭或不再需要时显式调用 clean 方法。清理操作是一个 Runnable ,当对象变为幻象可达时最多调用一次,除非它已经被显式清理。请注意,清理操作不得引用正在注册的对象。如果是这样,该对象将不会变为幻象可达,并且不会自动调用清理操作。

清洁动作的执行由与清洁器关联的线程执行。清除操作抛出的所有异常都将被忽略。清洁器和其他清洁操作不受清洁操作中异常的影响。该线程一直运行,直到所有已注册的清理操作都已完成并且清理器本身被垃圾收集器回收为止。

System.exit 期间清洁器的行为是特定于实现的。不保证是否调用清洁操作。

除非另有说明,否则将 null 参数传递给此类中的构造函数或方法将导致抛出 NullPointerException

API 注意:
只有在关联对象变为幻象可达后才会调用清理操作,因此实现清理操作的对象不持有对该对象的引用很重要。在此示例中,静态类封装了清洁状态和操作。不得使用匿名或非匿名的“内部”类,因为它隐含地包含对外部实例的引用,防止它变成幻象可达。选择新的清洁器还是共享现有的清洁器取决于用例。

如果在 try-finally 块中使用 CleaningExample,则 close 方法会调用清理操作。如果未调用 close 方法,则当 CleaningExample 实例变为幻象可访问时,Cleaner 将调用清理操作。


 public class CleaningExample implements AutoCloseable {
    // A cleaner (preferably one shared within a library,
     // but for the sake of example, a new one is created here)
    private static final Cleaner cleaner = Cleaner.create();

    // State class captures information necessary for cleanup.
    // It must hold no reference to the instance being cleaned
    // and therefore it is a static inner class in this example.
    static class State implements Runnable {

      State(...) {
        // initialize State needed for cleaning action
      }

      public void run() {
        // cleanup action accessing State, executed at most once
      }
    }

    private final State state;
    private final Cleaner.Cleanable cleanable;

    public CleaningExample() {
      this.state = new State(...);
      this.cleanable = cleaner.register(this, state);
    }

    public void close() {
      cleanable.clean();
    }
  }
  
清理操作可以是 lambda,但很容易捕获对象引用,通过引用被清理对象的字段,防止对象变为幻象可达。如上所述,使用静态嵌套类将避免意外保留对象引用。

清洁操作应准备好与其他清洁操作同时调用。通常,清理操作应该非常快速地执行而不是阻塞。如果清洁动作阻塞,它可能会延迟处理注册到同一清洁器的其他清洁动作。注册到清洁器的所有清洁操作应该相互兼容。

自从:
9
  • 方法详情

    • create

      public static Cleaner  create()
      返回一个新的 Cleaner

      清理器创建一个 daemon thread 来处理幻象可达对象并调用清理操作。线程的 上下文类加载器 设置为 system class loader 。该线程没有权限,仅在 SecurityManager is set 时强制执行。

      清洁器在幻象可达且所有已注册清洁操作完成时终止。

      返回:
      一个新的Cleaner
      抛出:
      SecurityException - 如果当前线程不允许创建或启动线程。
    • create

      public static Cleaner  create(ThreadFactory  threadFactory)
      使用 ThreadFactory 中的 Thread 返回一个新的 Cleaner

      线程工厂的 newThread 方法中的一个线程被设置为 daemon thread 并开始处理幻象可达对象并调用清理操作。在每次调用时,thread factory 必须提供适合执行清洁操作的线程。

      清洁器在幻象可达且所有已注册清洁操作完成时终止。

      参数:
      threadFactory - 一个 ThreadFactory 返回一个新的 Thread 来处理清洁操作
      返回:
      一个新的Cleaner
      抛出:
      IllegalThreadStateException - 如果来自线程工厂的线程是 not a new thread
      SecurityException - 如果当前线程不允许创建或启动线程。
    • register

      public Cleaner.Cleanable  register(Object  obj, Runnable  action)
      注册一个对象和一个清理操作,以便在对象变为幻象可达时运行。有关清洁操作行为的注意事项,请参阅上面的 API 说明
      参数:
      obj - 要监视的对象
      action - 一个 Runnable 在对象变为幻象可达时调用
      返回:
      一个Cleanable实例