2011-11-13 8 views
2

私はJava Stringクラスを読みましたが、不変でスレッドセーフですが、文字列の参照割り当てがスレッドセーフであるかどうかについてはまだ混乱しています。Javaで文字列を安全に設定/取得するには?

最初の質問:スレッドBがFoo.getString()を呼び出しながら、スレッドAがFoo.setString()を呼び出す場合、コードスレッドセーフ以下ですか?

Class Foo { 
    String aString; 
    public String getString() { 
     return aString; 
    } 
    public void setString(s) { 
     aString = s; 
    } 
} 

2番目の質問:上記のコードはスレッドセーフではない場合、私はFoo.getString()メソッドを書くのですか、ReentrantLockのを使用していますか?

Class Foo { 
    String aString; 
    ReentrantLock aLock; 
    public String getString() { 
     aLock.lock(); 
     return aString; 
     aLock.unlock(); // This line will be unreachable. How to fix?? 
    } 
    public void setString(s) { 
     aLock.lock(); 
     aString = s; 
     aLock.unlock(); 
    } 
} 

私はtryLock(タイムアウト)機能を使用する必要があるため、ReentrantLockを使用する必要があります。

+0

私の両方の質問に答えると答えを受け入れます。ありがとう。 – Lee

答えて

2

質問1:Eric Lippert wrote a very good blog post about it here ... aStringをvolatileと宣言すると、異なるスレッドの読み込みがすべて正しいことが保証されます。

質問2:

てみ使用して...最終的には最終的には例えば、ブロック内のロック解除、構築:

public String getString() { 
    try {   
    aLock.lock(); 
    return aString; 
    } finally { 
    aLock.unlock(); 
    } 
} 

public void setString(s) { 
    try {   
    aLock.lock(); 
    aString = s; 
    } finally { 
    aLock.unlock(); 
    } 
} 
+0

私の最初の質問についてもっと知りたいです。 – Lee

+0

@Lee更新を参照してください。 –

1

使用synchronizedキーワード:aStringは揮発作る

public synchronized String getString() { 
     return aString; 
    } 

    public synchronized void setString(s) { 
     aString = s; 
    } 
+0

申し訳ありません私の場合は、tryLock(タイムアウト)機能を使用する必要があるため、ReentrantLockを使用する必要があります。 – Lee

+0

大丈夫、気付かなかった。だから、他のポスターが示唆しているように、最終的にブロックされているほうが良い。 – aleroot

+0

なぜtryLockを使用する必要がありますか?この宿題かそのようなものですか? – James

2

がすべてですこの場合は必要です(つまり、書き込み後の読み込みで常に最新の値が表示されます)。メソッドの同期化は特に有用ではありません。私たちはexecuしかないからですどちらの場合も、より多くの作業(「StringがXYZの場合はXYAを代入する」と言う)をしたい場合は、より高いレベルの同期が必要になります。私。同期と揮発性の両方が同じ保証を提供します(クラス内の同期を他の場所で使用すると明らかな違いはありません)

揮発性は十分でパフォーマンスも高く、同期も同様です多くの競合アクセスがあった場合はそうでしたが、それ以外の点では重要ではありませんでした。同期は少なくともHotspot上の非競合アクセスに対して非常に最適化されています(ただし、すべての現代JVMに当てはまると仮定します)。

関連する問題