Cleaner
は、一連のオブジェクト参照および対応するクリーニング・アクションを管理します。
クリーニング・アクションは、オブジェクトがファントムに到達可能になったことをクリーナに通知した後に実行されるregisteredです。 クリーナは、PhantomReference
およびReferenceQueue
を使用して、reachabilityが変更されたときに通知を受けます。
各クリーナは独立して動作し、保留中のクリーニング・アクションを管理し、クリーナが使用されなくなったときにスレッド処理と終了を処理します。 オブジェクト参照と対応するクリーニング・アクションを登録すると、Cleanable
が返されます。 最も効率的な用途は、オブジェクトが閉じられているか不要になったときに、clean
メソッドを明示的に呼び出すことです。 クリーニング・アクションは、オブジェクトが明示的にクリーンアップされていないかぎり、ファントムに到達可能になったときに、最大で一度に呼び出されるRunnable
です。 クリーニング・アクションは、登録されているオブジェクトを参照してはいけません。 その場合、オブジェクトはファントムに到達できず、クリーニング・アクションは自動的に呼び出されません。
クリーニング・アクションの実行は、クリーナに関連付けられたスレッドによって実行されます。 クリーニング・アクションによってスローされたすべての例外は無視されます。 クリーナおよびその他のクリーニング・アクションは、クリーニング・アクションの例外の影響を受けません。 スレッドは、登録されているすべてのクリーニング・アクションが完了し、ガベージ・コレクタによってクリーナ自体が再利用されるまで実行されます。
System.exit
中のクリーナの動作は、実装に固有です。 クリーニング・アクションが呼び出されるかどうかに関して保証はありません。
ほかで指定がない場合、null
引数をコンストラクタまたはこのクラスのメソッドへ渡すと、NullPointerException
がスローされます。
- APIのノート:
- クリーニング・アクションは、関連付けられたオブジェクトがファントムに到達可能になったあとでのみ呼び出されるため、クリーニング・アクションを実装するオブジェクトがオブジェクトへの参照を保持しないことが重要です。 この例では、静的クラスがクリーニングの状態とアクションをカプセル化します。 "inner"クラスは、匿名かどうかにかかわらず、外部インスタンスへの参照が暗黙的に含まれているため、ファントムに到達できないようにするため、使用しないでください。 新しいクリーナの選択または既存のクリーナの共有は、ユースケースによって決まります。
CleaningExampleがtry-finallyブロックで使用されている場合、
close
メソッドはクリーニング・アクションを呼び出します。close
メソッドがコールされない場合、CleaningExampleインスタンスがファントムに到達可能になったときに、クリーニング・アクションがクリーナによってコールされます。
クリーニング・アクションはラムダになる可能性がありますが、消去されるオブジェクトのフィールドを参照して、オブジェクトがファントムに到達できないようにすることで、オブジェクト参照を簡単に取得できます。 前述のように、静的なネストされたクラスを使用すると、オブジェクト参照が誤って保持されることを回避できます。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(); } }
クリーニング・アクションは、ほかのクリーニング・アクションと同時に呼び出されるように準備してください。 通常、クリーニング・アクションは、ブロックするのではなく、非常に迅速に実行するようにしてください。 クリーニング・アクションがブロックされると、同じクリーナに登録されているほかのクリーニング・アクションの処理が遅延することがあります。 クリーナに登録されているすべてのクリーニング・アクションは、相互に互換性があるはずです。
- 導入されたバージョン:
- 9
-
ネストされたクラスのサマリー
-
メソッドのサマリー
修飾子と型メソッド説明static Cleaner
create()
新しいCleaner
を返します。static Cleaner
create
(ThreadFactory threadFactory) ThreadFactory
からThread
を使用して新しいCleaner
を返します。オブジェクトと、オブジェクトがファントムに到達可能になったときに実行するクリーニング・アクションを登録します。
-
メソッドの詳細
-
create
public static Cleaner create()新しいCleaner
を返します。クリーナは、ファントム到達可能オブジェクトを処理し、クリーニング・アクションを起動する
daemon thread
を作成します。 スレッドの「コンテキスト・クラス・ローダー」は「システム・クラス・ローダー」に設定されます。 スレッドには権限がありません。これは、「SecurityManager
が設定されている」の場合のみ適用されます。クリーナは、ファントム到達可能で、登録されているすべてのクリーニング・アクションが完了すると終了します。
- 戻り値:
- 新しい
Cleaner
- 例外:
SecurityException
- 現在のスレッドがスレッドの作成または起動を許可されていない場合。
-
create
public static Cleaner create(ThreadFactory threadFactory) ThreadFactory
からThread
を使用して新しいCleaner
を返します。スレッド・ファクトリの
newThread
メソッドのスレッドは、「デーモン・スレッド」に設定され、ファントム到達可能オブジェクトを処理してクリーニング・アクションを起動するために起動されます。 「スレッド・ファクトリ」は、各コールで、クリーニング・アクションの実行に適したスレッドを指定する必要があります。クリーナは、ファントム到達可能で、登録されているすべてのクリーニング・アクションが完了すると終了します。
- パラメータ:
threadFactory
- 新しいThread
を返してクリーニング・アクションを処理するThreadFactory
- 戻り値:
- 新しい
Cleaner
- 例外:
IllegalThreadStateException
- スレッド・ファクトリからのスレッドが「新しいスレッドではありません」の場合。SecurityException
- 現在のスレッドがスレッドの作成または起動を許可されていない場合。
-
register
public Cleaner.Cleanable register(Object obj, Runnable action) オブジェクトと、オブジェクトがファントムに到達可能になったときに実行するクリーニング・アクションを登録します。 クリーニング・アクションの動作については、前述の「APIノート」を参照してください。- パラメータ:
obj
- 監視するオブジェクトaction
- オブジェクトがファントム到達可能になったときに呼び出すRunnable
- 戻り値:
Cleanable
インスタンス
-