Clojure言語を拡張して、ACI保証の参照をACID保証のdref(耐久性のある参照)に拡張しようとしています。APIは、単純にを呼び出すためのものです(dref key value)
。ここでkey
、は基になるデータストア(現在の実装ではBDB JE)で使用されるキーの文字列でありvalue
、drefを初期化する必要があるオブジェクトです。key
DBにすでに存在する場合は、代わりに保存された値が使用されます。
同じキーで複数のdrefを作成でき、それらを同期する必要があります。つまり、キー「A」を持つ1つのdrefが、キー「A」で書き込まれたり読み取られたりするトランザクションに参加する場合、(ensure)
キー「A」を持つ他のすべてのdrefはトランザクションである必要があります。同期:読み取りロックと書き込みロックを使用して、これらのdrefを含むトランザクションに順序を付ける必要があります。より広い意味では、同じキーを持つ複数のメモリ内drefが存在する場合がありますが、そのキーを持つすべてのdrefは単一の論理オブジェクトです。
明らかな理由から、この単一の論理drefが単一の具象インメモリdrefで実装されていることを確認する方がはるかに簡単です。そうすれば、同期するものは何もありません。どうすればよいですか?
明白な答えは、keyにキー設定されたオブジェクトプールを使用することです。次に、Clojureは静的getInstance(key,value)
メソッドを呼び出して、存在する場合はプールから取得し、存在しない場合は作成してプールにデータを入力します。このアプローチの問題は、完了時にClojureにオブジェクトを解放させる簡単な方法がないことです。メモリリークのある都市。強い参照を持つオブジェクトが収集されないようにし、それらがプールに存在するようにする必要があります。別のプロセスが同じキーを持つ新しいdrefを作成する可能性があり、同じキーを持つ他のdrefとのトランザクションの安全性がないため、プールがまだ使用されている論理drefへの参照を失うと悲惨なことになります。
そのため、強くない参照を使用したバージョンWeakHashMap
または何かが必要です(SoftReference
GCでもう少し気が進まない場合は、を使用することをお勧めします)。それで:
- を使用する
HashMap<String,SoftReference<DRef>>
場合、エントリの値(SoftReference)が収集された場合に、マップがエントリを削除するようにするにはどうすればよいですか?ある種のデーモンスレッド? - GCのプールをスレッドセーフにするにはどうすればよいですか?
SoftReference
または、GCがレベルで動作していて、デーモンスレッドがそのレベルで動作しているので、それについて心配する必要はありませんMap
か? - 関連するメモとして、デーモンスレッドが実行されていることを確認するにはどうすればよいですか?キャッチされない場合にJVM全体をクラッシュさせる例外をスローせずに停止できる方法はありますか?その場合、必要に応じて新しいものを監視して開始するにはどうすればよいですか?