2

のセマンティクスは何AtomicReferenceですか?
私が行った場合:

AtomicReference<CustomObject> ref = new AtomicReference<CustomObject>();

そして私はします:

public void someMethod(){  
 //do something  

 ref.set(loadNewData());  

}  

private final Sempahore updatePermit = new Sempahore(1);  

private CustomObject loadNewData(){  
     CustomObject obj = null;  
     if (updatePermit.tryAcquire()) {  
        obj = ...; //do the loading and create Object  
        updatePermit.release();  
    } else {  
        //update already running, wait  
        updatePermit.acquire();  
        //release the permit immediately  
        updatePermit.release();  
        obj = ref.get(); //????
    }  
    return obj;    
}    

オンラインで最も新しいバージョンが返されるという保証はありますか?これは、投稿 に対するassyliasの回答に関連しています:obj = ref.get(); //????getCustomObject

4

4 に答える 4

3

はい。
AtomicReference出版を保証します。

ただし、別のスレッドが1ミリ秒後に設定しないという保証はありません。

compareAndSet()を呼び出していない場合は、フィールドAtomicReferenceよりも優れていることに注意してください。volatile

于 2012-11-13T14:29:15.397 に答える
3

のJavaDocをjava.util.concurrent.atomic読む:

  • getvolatile変数を読み取るメモリ効果があります。

  • set変数を書き込む(割り当てる)というメモリ効果がありvolatileます。

したがって、保証は次のとおりです。get() 常に最後に渡された値を返しますset()。その間に何をするか、どのような種類のロックを使用するかなどは関係ありません。volatile変数の変更(効果的に行う)は、その値を読み取る他のすべてのスレッドによって表示されることが保証されます。

于 2012-11-13T14:30:51.057 に答える
3

実際、コードには競合状態があり、新しいデータが失われる可能性があります。

  1. 最初の呼び出し元はloadNewDataに入り、新しいデータのロードを開始します(セマフォがあります)
  2. 2番目の呼び出し元はセマフォを取得できず、取得を待機します
  3. 最初の呼び出し元がロードを終了し、セマフォを解放します(ただし、新しいデータはまだ返されません)
  4. 2番目の発信者はセマフォを取得し、古いデータを呼び出しref.get()て取得します
  5. 最初の呼び出し元は、に渡される新しいデータを返しますref.set()
  6. 2番目の呼び出し元は、渡されたときに新しいデータを上書きする古いデータを返しますref.set()

someMethod()常に新しいデータをロードしており、新しいデータがロードされている間は常に呼び出し元が待機するようにしたいので、これらの余分なものはすべて役に立ちません。ブロック全体の周りに単純な同期ブロック(またはロック)を使用して、アトミック参照を破棄するだけです。リンクされた投稿によると、これは一度だけやりたいようですので、初期化されたフラグを使用してください。

private boolean _initialized;

public synchronized void loadLatestData() {
  if(!_initialized) {
      // load latest data ...
      _initilized = true;
  }
}
于 2012-11-13T14:32:42.883 に答える
1

アトミック変数(を含む)は、スレッド間で発生前の関係を確立するという点で、フィールドAtomicReferenceと同じプロパティを持っています。volatile1つのスレッドAが揮発性フィールド(またはアトミック変数)に値を書き込み、別のスレッドBが同じ変数から読み取る場合、 BAの変更を確認するかどうかを必ずしも保証することはできませんが、次のことを保証できます。

  • Bが Aによって書かれた値を見た場合
  • 次に、 Bは、 Aが揮発性フィールドに書き込む前に行った他のフィールド(揮発性および不揮発性)への書き込みの結果も表示します。
于 2012-11-13T14:43:58.623 に答える