複雑なマップがあります。複雑なマップは頻繁に取得されたり、まれにしか変更されないため、ロックされていないため、キーによって参照される要素の動作が一意に決定されます。java:データを公開するためのvolatile配列
つまり、キーが同じ場合、キーが参照する構造体は常に同じ動作をします。実際には、キーは不変finalであり、参照される値は事実上finalおよび/またはthreadsafeです。
私は、カスタムハッシュマップの参照の根本的な揮発性配列への揮発性の参照を持っていると言います。この配列のハッシュマップアルゴリズムはar.lengthメンバーをモジュラスとして使用しているので、get関数で呼び出し元が非現在の配列を参照すると、その参照はすべて良好で、依然としてハッシュスロットに従います。ミューテックスなしで成功し、null以外の値を取得すると、それは正しいものです。
私の計画は、getが失敗するたびに、呼び出し側がキーの正しい値を構築し、他のputとの相対的なロックを行い、オブジェクトを配列に埋め込むputを行います。クリティカルセクションを終了する直前に、putコードは揮発性配列フィールド "ar"を自身に再割り当てします。おそらく、コンパイラとホットスポットコンパイラへのメッセージとして、揮発性配列参照を使用してハッシュ値を検索するgetsに対して相対フェンスを作成します。
これは、限り、コンパイラは「= AR AR」NOPしないように動作します割り当て:揮発性書き込みが離れて最適化することができない
private volatile Object[] ar;
public Object get (Object key)
{
Object[] ar = this.ar;
// get the value from the correct hash slot
}
public synchronized Object put (Object key, Object val) {
{
... stuff a new object into the correct hash slot
ar = ar; // will the compiler truly compile this statement with
// normal volatile fencing relative to the get function??
... if a race condition causes a value to already be mapped, return and use that
... rather than the one we created and passed to put (different than normal put
... contract)
}