15

Javaでメンバー変数を揮発性として宣言する場合、これは、すべてのオブジェクトのデータが揮発性メモリに格納されることを意味しますか、それともオブジェクトへの参照が揮発性メモリに格納されることを意味しますか?

たとえば、次のクラスがある場合:

class C{
   int i = 0;
   char c = 'c';
}

そのインスタンスを次のように宣言すると、次のようになります。

private volatile C obj;

それはへの参照をobj揮発性メモリに保存しますか、それともobjのデータ(obj.iおよびobj.c)をvolatileメモリに保存しますか?

スレッドセーフにobj.cなりobj.iますか?

4

4 に答える 4

27

はい、オブジェクト参照のみがJVMによって揮発性であると見なされ、ヒープ上に存在するオブジェクトデータ自体は見なされません。ヒープ上のオブジェクトのメンバー変数を揮発性にする必要がある場合は、もちろん、それらのプリミティブにキーワードを適用できます。

class C {
   volatile int i = 0;
   volatile char c = 'c';
}

再:これが変数スレッドを安全にするかどうかのあなたの質問は、あなたが変数をどのように使用しているかに依存します。@gerrytanがOracleのドキュメントから指摘しているように、volatileキーワードは、読み取りまたは書き込みをアトミックにするのに役立ちますが、これは常にスレッドセーフであるのと同じではないことに注意してください。次のコードを検討してください...

if(obj != null) {
    obj.doSomething();
}

nullチェックを実行するスレッドが、実行前に中断されobj.doSomething()、別のスレッドがが設定される可能性がありますobj = nullsynchronizedここでは、ブロックなどの他のメカニズムが必要です。

于 2013-03-18T21:54:24.193 に答える
5
private volatile C obj;

それはobj揮発性だけになります。

obj.cとobj.iのスレッドを安全にしますか?

いいえ。スレッドセーフにするには、アクセスを同期する必要があります。

于 2013-03-18T21:49:59.907 に答える
3

これにより、オブジェクト参照が揮発性になるだけです。obj.iとobj.cも揮発性にするためには、それらを明示的に揮発性にする必要があります

class C{
   volatile int i = 0;
   volatile char c = 'c';
}
于 2013-03-18T21:50:55.610 に答える
1

Javaでメンバー変数を揮発性として宣言する場合、これは、すべてのオブジェクトのデータが揮発性メモリに格納されることを意味しますか、それともオブジェクトへの参照が揮発性メモリに格納されることを意味しますか?

オブジェクトを揮発性として宣言すると、実際には、基盤となるプロセッサに揮発性オブジェクトの操作方法を指示します。CPU命令によって読み取られるたびに、ヒープから新しいコピーが呼び出され、オブジェクトへの書き込みが行われるたびに保存されます。ヒープに追加し、他のスレッドで使用できます。したがって、プロセッサはキャッシュから古い値を選択せず​​、キャッシュに書き込みもせず、キャッシュがヒープに書き戻されるのを待ちます。

obj.cとobj.iのスレッドを安全にしますか?いいえ。オブジェクトを読み取るときに常に新しいコピーがあることを保証するだけです。変数と変数値に基づく処理ロジックを使用しているときに、誰かがバックグラウンドで値を変更した可能性があります。それを更新しました、あなたは別の値を更新しています。

于 2013-05-14T10:06:55.657 に答える