0

揮発性書き込みは、あるスレッドで他のスレッドに表示される前に、書き込み (不揮発性/揮発性書き込み) が発生することを保証しますか?

次のコードは常に90,80出力として生成されますか?

public class MyClass
{
    private boolean flag = false;
    private volatile int volatileInt = 0;
    private int nonVolatileInt = 0;
    public void initVariables()
    {
        nonVolatileInt = 90; // non-volatile write
        volatileInt = 80; // volatile write
        flag = true; // non-volatile write
    }
    public void readVariables()
    {
        while (flag == false)
        {}
        System.out.println(nonVolatileInt + ","+ volatileInt);
    }
    public static void main(String st[])
    {
        final MyClass myClass = new MyClass();
        Thread writer = new Thread( new Runnable()
        {
            public void run()
            {
                myClass.initVariables();
            }
        });
        Thread reader = new Thread ( new Runnable()
        {
            public void run()
            {
                myClass.readVariables();
            }
        });
        reader.start();writer.start();
    }
}

私の懸念はメソッド initVariables() です。JVM には、次の方法でコード ブロックを自由に並べ替えることができませんか?:

flag = true;
nonVolatileInt = 90 ; 
volatileInt = 80;

その結果、次のようにリーダー スレッドによって出力を取得します。 0,0
または、次の方法で並べ替えることができます。

nonVolatieInt = 90;
flag = true;
volatileInt = 80;

その結果、リーダースレッドによる出力は次のようになります。90,0

4

1 に答える 1

5

揮発性書き込みにより、この書き込みの後に既に実行された書き込みが表示されないことが保証されます。ただし、これを確認するには、最初に揮発性読み取りを実行する必要があります。

その結果、リーダースレッドによる出力は次のようになります。90,0

正しい。ただし、読み取りを正しく実行すると、取得できません0, 80

0, 0 - ok
90, 0 - ok
90, 80 - ok
0, 80 - breaks happens before.

ただし、揮発性の読み取りを最初に実行しないため、読み取りは動作の前に発生することを保証しません。

System.out.println(nonVolatileInt + ","+ volatileInt);

これにより、最初に不揮発性フィールドが読み取られるため、古いバージョンの不揮発性フィールドと新しいバージョンの揮発性フィールドが表示されます。

注: 実際には、問題が発生する可能性はほとんどありません。これは、キャッシュが一度にキャッシュ ライン全体を無効にし、これらのフィールドが同じ 64 バイト ブロック内にある場合、不整合が発生しないためです。

問題になる可能性が高いのは、このループです。

 while (flag == false)
    {}

問題は; JIT は、スレッドが決して書き込みをflag行わないことを確認できるため、値をインライン化できます。つまり、値を読み取る必要はありません。これにより、無限ループが発生する可能性があります。

http://vanillajava.blogspot.co.uk/2012/01/demonstrating-when-volatile-is-required.html

于 2014-05-05T11:04:19.930 に答える