9

私が次のものを持っているとしましょう、

public class Foo{
    private String bar;

    public String getBar(){
        return bar;
    }

    public void setBar(String bar){
        this.bar = bar;
    }
}

これらのメソッドは、クラスの不変の性質のために自動的にスレッドセーフですかString、それとも何らかのロックメカニズムが必要ですか?

4

4 に答える 4

19

いいえ、これはスレッドセーフではありません。Fooは可変であるため、異なるスレッドが同じ値、barつまり一貫性を確実に認識できるようにする場合は、次のいずれかを実行します。

  • 作るbar volatile、または
  • メソッドを作成するsynchronized、または
  • を使用しAtomicReference<String>ます。

の読み取りと書き込みbarはそれ自体がアトミックですが、アトミック性はスレッドセーフではありません。

http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html


Java並行性の詳細については、Java並行性の実践(別名JCIP)のコピーを入手してください。

于 2013-02-25T17:18:56.123 に答える
7

参照を設定しているため、String不変性は機能しません。の内容には影響していませんString

于 2013-02-25T17:19:30.077 に答える
5

いいえ、安全ではありません。

これはFooの可変動作です。文字列の不変性はFooには発生しません。

public class Foo{
    private String bar;

    public synchronized String getBar(){
        return bar;
    }

    public synchronized void setBar(String bar){
        this.bar = bar;
    }
}
于 2013-02-25T17:18:50.447 に答える
3

いいえ、スレッドセーフではありません。

Stringは不変ですが、問題はのフィールドから発生しますFoo。これをより明確にするために、たとえば、の値を(置き換えるのではなく)追加barすることが仕事となるメソッドを考えてみましょう。複数のスレッドから呼び出されると、一部の書き込みが失われる可能性があります。この場合、最初は明らかでなくても、同じ(書き込みの損失)が単純なセッターでも発生する可能性があります。

于 2013-02-25T17:23:17.737 に答える