オブジェクトが到達可能性の状態を変更すると、オブジェクトへの参照が参照キューに配置される場合があります。これらのキューは、オブジェクトのアクセシビリティの変更についてコードと通信するために、ゴミコレクターによって使用されます。これらのキューは、アクセシビリティの変更を検出するための最良の方法ですが、GETメソッドの返品値がnullかどうかを確認することで、オブジェクトのアクセシビリティの変更を検出することもできます。
参照オブジェクトは、構築されたときに特定のキューに関連付けることができます。参照の各サブクラスは、次の形式のコンストラクターに次を提供します。
.public strength reference(t Reference、ReferenceQueUQ):このメソッドは、指定された参照オブジェクトを使用して新しい参照オブジェクトを作成し、指定されたキューに参照オブジェクトを登録します。 Garbage Collectorが参照オブジェクトが表す特定の到達可能性状態に入ると判断した後、弱い参照とソフト参照がキューに挿入され、両方の参照が挿入キューの前にクリアされます。 Garbage Collectorがその参照オブジェクトが仮想範囲の状態に入ったと判断した後、仮想参照もキューに挿入されますが、それらはクリアされません。 Garbage Collectorによって参照オブジェクトがキューに挿入されると、GETメソッドの戻り値は間違いなくnullになるため、オブジェクトを復活させることはできません。
参照オブジェクトを参照キューに登録しても、キューと参照オブジェクトの間に参照は作成されません。参照オブジェクト自体が到達不可能になった場合、キューに挿入することはできません。したがって、当社のアプリケーションは、参照されるすべてのオブジェクトへの強力な参照を維持する必要があります。
参照クラスは、キュー内の参照を削除する3つの方法を提供します。
ポーリング方法により、スレッドは参照がキューにあるかどうかを照会し、キューに参照が存在するときに特定のアクションを実行できます。削除方法は、より複雑な(一般的ではない)状況を処理できます。ここでは、専用のスレッドがキューから参照を削除し、適切なアクションを実行する責任があります。これらのメソッドのブロッキング動作は、object.waitで定義されたブロッキング動作と同じです。特定の参照のために、Isenquedメソッドによってキューにあるかどうかを照会するか、そのEnqueueメソッドを呼び出すことでキューに押し込むことができますが、通常、この種のプラグはガベージコレクターによって行われます。
参照キューの仮想参照を使用して、オブジェクトをいつリサイクルできるかを判断できます。仮想参照のGETメソッドは常にnullを返すため、オブジェクトが他の方法で到達可能であっても、仮想参照を介してオブジェクトにアクセスすることはできません。実際、仮想参照を使用してオブジェクトをリサイクルすることを見つけることが最も安全な方法です。なぜなら、オブジェクトを終了すると、弱い参照とソフト参照がキューに挿入されるため、終端オブジェクトが終了した後に仮想参照がキューに挿入されます。可能であれば、他の参照が最終的なメソッドを使用する可能性があるため、仮想参照を常に使用する必要があります。
外部リソースコレクションへのアクセスを制御できるリソースマネージャーの例を考えてみましょう。オブジェクトは、外部リソースへのアクセスを要求し、操作が完了するまでアクセスを終了しません。その後、リソースマネージャーに使用されるリソースを返す必要があります。このリソースが共有される場合、その使用権は複数のオブジェクト間で渡され、複数のスレッド間で渡される可能性があるため、このリソースの最後のユーザーであるオブジェクトを決定することは困難であるため、どのコードがこのリソースを返す責任を負うかを判断することは困難です。この状況を処理するために、リソースマネージャーは、キーと呼ばれる特別なオブジェクトにリソースを関連付けることにより、このリソースの自動リサイクルを実現できます。キーオブジェクトが到達可能である限り、このリソースはまだ使用されていると思います。キーオブジェクトをゴミとして収集できる限り、リソースは自動的にリリースされます。次のコードは、上記のリソースの抽象的な表現です。
インターフェイスリソース{void use(object key、object…args); void release(); }リソースが取得される場合、その重要なオブジェクトをリソースマネージャーに提供する必要があります。返されたリソースインスタンスの場合、このリソースは、対応するキーを取得した場合にのみ使用できます。これにより、キーがリサイクルされた後、このリソースを表すリソースオブジェクトにアクセスできる場合でも、対応するリソースを使用できなくなります。リソースオブジェクトは、重要なオブジェクトへの強力な参照を保存しないことに注意してください。これは重要なことです。これにより、キーオブジェクトが到達不可能になり、リソースが取得できなくなるため、重要です。リソースの実装は、リソースマネージャーにネストできます。
Private Static Class ResourceIMPLはリソースを実装しています{int keyhash; Boolean NeedsRelease = false resourceImpl(object key){keyhash = system.identityhashcode(key); // =外部リソースのセットアップneedsrelease = true; } public void use(object key、object ... args){if(system.identityhashcode(key)!= keyhash)スロー新しいIlleqalargumentexception( "誤ったkey" //... suse the resoung} public synchronized lileasキーオブジェクトのハッシュコードは、リソースが作成されたときに保存され、使用方法が呼び出されるたびに、同じキーが提供されるかどうかをチェックします。リソースの実際の使用も同期する必要がある場合がありますが、簡単にするために、ここでは省略します。リリース方法は、リソースのリリースを担当します。使用後、またはキーオブジェクトが参照されなくなった場合のリソースマネージャーによって直接呼び出されます。独立したスレッドを使用して参照キューを監視するため、リリース方法を同期し、複数の呼び出しを許可する必要があります。
実際のリソースマネージャーには、次のフォームがあります。
Public Final Class ResourceManager {Final ReferenceQueue
キーオブジェクトは、リソースマネージャーにキーオブジェクトを割り当てることと比較して、リソースユーザーが大きな柔軟性を与えるオブジェクトを任意のオブジェクトにすることができます。 GetResourceメソッドが呼び出されると、新しいリソースワークMPLオブジェクトが作成され、メソッドに提供されたキーが新しいResourceIMPLオブジェクトに渡されます。次に、仮想リファレンスが作成され、その参照オブジェクトがメソッドに渡されるキーであり、この仮想リファレンスはリソースマネージャーのリファレンスキューに挿入されます。最後に作成された仮想参照オブジェクトと参照オブジェクトは、マッピングテーブルに保存されます。このマッピングテーブルには2つの目的があります。1つはすべての仮想リファレンスオブジェクトを到達可能に保つことであり、もう1つは各仮想参照に関連付けられた実際のリソースオブジェクトをクエリする便利な方法を提供することです。 (別の方法は、ファントミレファレンスをサブクラス化し、リソースオブジェクトをフィールドに保存することです。)
キーオブジェクトが到達不可能になった場合、リソースマネージャーは別の「リーパー」スレッドを使用してリソースを処理します。シャットダウン方法は、ハーベスタースレッドを終了することにより(割り込みに応じて)エクスプローラーを「閉じ」、getResourceメソッドがIlle-llestateExceptionの例外をスローさせます。このシンプルなデザインでは、エクスプローラーが閉じた後にキューに接続する参照は処理されません。実際のハーベスタースレッドは次のとおりです。
class reaperthread extends thread {public void run(){//中断されるまで実行(true){try {reference ref = queue.remove();リソースres = null;同期(resourcemanager.this){res = refs.get(ref);参照。削除(ref); } res .release(); ref.clear(); } catch(arternedexception ex){break; // all done}}}}}ReaperThreadは内部クラスであり、指定されたHarvesterスレッドは、関連するリソースマネージャーが閉じられるまで実行されます。特定のキーに関連付けられた仮想参照が参照キューに挿入されるまで、スレッドは削除メソッドのブロックをブロックします。この仮想参照は、マッピングテーブルからリソースオブジェクトへの参照を取得でき、この「キーから参照」ペアはマッピングテーブルから削除されます。その直後、リリース方法がリソースオブジェクトに呼び出され、リソースをリリースします。やっと、
仮想参照は、キーをリサイクルできるようにクリアされます。
独立したスレッドを使用する代わりに、参照キューのポーリングメソッドを呼び出し、キーが到達できなくなったすべてのリソースをリリースする任意の操作は、getResource「メソッド」に置き換えられ、最終的な投票操作を実行するためにも使用できます。リソースマネージャーのセマンティクスは、実際のリソースタイプとリソースの使用パターンに依存します。
参照キューを使用した設計は、終端を直接使用するデザイン(特に仮想参照)よりもはるかに信頼性があります。ただし、参照キューに挿入された参照オブジェクトの正確な時間と位置は定かではないことを覚えておく必要がありません。また、アプリケーションが終了したときにすべてのプラグ可能な参照が参照キューに挿入されたかどうかも確認する必要がありません。アプリケーションが終了する前にすべてのリソースをリリースできることを確認する必要がある場合は、必要なシャットダウンフックをインストールするか、アプリケーションによって定義された他のプロトコルを使用して、これが達成されることを確認する必要があります。