2012-05-15 6 views
12

volatileキーワードを非プリミティブとしても使用するかどうかはわかりません。私は1つのスレッドによってセット/割り当てられ、別のスレッドによってアクセスされるクラスメンバーを持っています。このメンバをvolatile宣言する必要がありますか?java-volatileキーワード(非プリミティブの場合)

private /* volatile */ Object o; 

public void setMember(Object o) { 
    this.o = o; 
} 

public Object getMember() { 
    return o; 
} 

ここで、setMember(...)は1つのスレッドから呼び出され、getMember()は別のスレッドから呼び出されます。

たとえば、ブール値の場合、答えは「はい」になります。

私はJava 1.4を使用していますが、この場合のメンバーは読み取り専用です。だから私はこのケースでは可視性を気にしているので、volatileキーワードについての私の質問です。

答えて

11

はい - volatileは、プリミティブ型フィールドの参照型フィールドとまったく同じ意味を持ちます。参照型の場合、フィールドが参照するオブジェクトのメンバは、マルチスレッドアクセス用に設計する必要があります。

+0

フィールドが参照するオブジェクトのメンバも、マルチスレッドアクセス用に設計されている必要があります。なぜそうであるのかについては、拡張することができますか? – jtkSource

+0

@jtkSource:volatileはフィールドのみに影響しますが、フィールドには参照のみが含まれています。 volatileは、他のスレッドがその参照の更新を参照するようにしますが、参照されるオブジェクトがvolatileまたは同期を適切に使用しない場合、他のスレッドはそのオブジェクトのフィールドの更新を見ることができません。 –

+0

念のため、揮発性変数がオブジェクトを参照する場合、不揮発性変数もvolatile宣言されたオブジェクトの文脈内で一貫した方法で 'visibile'にされませんか?これを「オブジェクト参照」とも呼ばれる他のオブジェクトが非揮発性の方法で存在する場合、それらのオブジェクトだけが一貫した状態で変数を参照する危険性がありますか?記憶に同じ物体の表現が2つある可能性はありますか? - 私の論理を混乱させるかどうかを教えてください。 – jtkSource

6

参考にすることもできますが、キーワードは参照の設定にのみ適用されます。そのオブジェクト内のプロパティのマルチスレッド可視性には影響しません。ステートフルな場合は、とにかく各アクセスを同期させて、希望する先起こりの関係を確実にしたいと思うでしょう。

4

はい、コードは正しいです。この場合、参照自体は揮発性であるため、参照へのチャンスは他のすべてのスレッドで自動的に表示されますが、参照されるオブジェクトに対する変更は表示されません。

0

我々はAtomicIntegerクラスを見れば、それはvaluevolatileなどを宣言している、だから、どのスレッドキャッシュの問題がなく、マルチスレッド環境で使用することができます。

しかし、あなたがAtomicIntegerを参照していると思うなら、それは多くのスレッドによって異なるAtomicIntegerオブジェクトで変更されます。その参照に対しても揮発性が必要です。

private volatile AtomicInteger reference = new AtomicInteger(0); 

大部分はそうではありません。オブジェクトの値のみが変更されます。最終的に宣言します。

関連する問題