1

これは AtomicReference を使用するのと同じくらい安全ですか?

private volatile String myMember;

public void setMyMember(String s) { 
   myMember = s;
}

対。

private final AtomicReference<String> myMember = new AtomicReference<>();

public void setMyMember(String s) {
    while (true) {
        String current = myMember.get();
        if (myMember.compareAndSet(current, s))
            break;
    }
}    
4

2 に答える 2

5

あなたのコードは「安全」ですが、コードと同じことをしませんAtomicReference。通常、AtomicReferencewith ループcompareAndSetは、誰かがリストまたはオブジェクトに何かを追加しようとしていて、複数のスレッドで競合状態から保護したい場合に使用されます。

例えば:

private final AtomicReference<List<String>> listRef = new AtomicReference<>();
...
while (true) {
    List<String> currentList = listRef.get();
    List<String> newList = new ArrayList<String>(currentList);
    newList.add(stringToAdd);
    // if we update the list reference, make sure we don't overwrite another one
    if (listRef.compareAndSet(currentList, newList))
        break;
}

あなたの場合、単純なStringオブジェクトを使用しているため、作成するだけでvolatile問題ありません。をしても意味がありませんcompareAndSet。それでも を使用したい場合はAtomicReference、 を呼び出してmyMember.set(...)ください。

于 2012-08-22T16:48:18.533 に答える
3

最初のコード スニペットは完全にスレッド セーフであり、Stringスレッド セーフであり、変数への割り当てがアトミックであるため、十分です。

2 番目のものはあまり意味がありません。このような構造は内部で使用されます。たとえばAtomicInteger、並行環境で割り当てを無視しないようにするためです。volatileあなたの場合は大丈夫です。

于 2012-08-22T16:48:36.407 に答える