2017-09-16 7 views
1

の下でこの記事をオブジェクトのフィールドを読んだが、読んだ後に育った:https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#pitfall-semi-syncオブジェクトへの参照を読み取り、JMM

class Box { 
    int x; 
    public Box(int v) { 
    x = v; 
    } 
} 

class RacyBoxy { 
    Box box; 

    public synchronized void set(Box v) { 
    box = v; 
    } 

    public Box get() { 
    return box; 
    } 
} 

とテスト:

@JCStressTest 
@State 
public class SynchronizedPublish { 
    RacyBoxy boxie = new RacyBoxy(); 

    @Actor 
    void actor() { 
    boxie.set(new Box(42)); // set is synchronized 
    } 

    @Actor 
    void observer(IntResult1 r) { 
    Box t = boxie.get(); // get is not synchronized 
    if (t != null) { 
     r.r1 = t.x; 
    } else { 
     r.r1 = -1; 
    } 
    } 
} 

著者はそれがr.r1 == 0ことは可能であると述べています。私は と同意します。しかし、私は説明と混乱しています:

実際の失敗は、オブジェクトへの参照の読み取りとオブジェクトのフィールドの読み取りがメモリモデルでは異なるという事実に起因します。

私は

はオブジェクトへの参照を読み取り、オブジェクトのフィールドを読み込むことに同意しますが、私はそれが結果に影響を与える方法を見ていない、メモリモデルの下に別個のものである けど。

ご理解ください。

P.S.誰かが混乱している場合@Actor。単にスレッド内で実行するという意味です。

答えて

1

私は、これは、連続したコンプライアンスに関してコードを読む人々の共通のアイディアを強調していると思います。インスタンスへの参照が1つのスレッドで利用できるという事実は、そのコンストラクタが設定されていることを意味しません。つまり、インスタンスを読み取ることは、インスタンスのフィールドを読み取ることとは異なります。多くの人は、一度インスタンスを見ることができれば、コンストラクタを実行する必要があると考えていますが、読込み同期が失われているため、これは上記の例では当てはまりません。

+0

そうですか? 最初のスレッド(アクター)が参照を公開しましたが、オブジェクトは初期化されていませんでした。次に、オブザーバがボックスへの参照を読み込み( 'boxie.get()')、参照が 'null 'でなかったので、オブザーバは' t.x == 0'を読み込みます。 – Gilgamesz

+0

はい、インスタンスのパブリッシュとそのコンストラクタの呼び出しは、オブジェクトのパブリッシュを安全にしない限り、アトミックではありません。 –

1

病気は少しだけここに受け入れ答えを強化 - 一部障壁ずにリファレンスを参照してくださいたら(一部のスレッドが参照を手に入れることができると思う)という保証は絶対ありません - そのコンストラクタからすべてのフィールドを初期化されます。私が間違っていないなら、私は実際にあなたの質問の1つにこれまでにある種の答えをしました。

最終フィールドがLoadLoadと​​のコンストラクタの後に2つのバリアが挿入されています。それはあなたが彼らの名前について考える - あなたはそれコンストラクタが内1 で再注文することができ後無操作ことがわかります:

また
Load -> Load (no Load can be re-ordered with a previous Load) 
Load -> Store (no Store can be re-ordered with a previous Load) 

は、あなたが破損することは不可能であろうことに注意してくださいそれは現在のx86のメモリモデルの下で - それは(あまりにも)強烈なメモリモデルです。これらの障壁はとなります。x86となります。操作は並べ替えられていないため、全く挿入されません。

+0

追加の観点から@Eugeneに感謝します。 – Gilgamesz

関連する問題