7

volatileキーワードは、変数の書き込み操作の前にメモリバリアを追加できると言われました。だから私はコードを書く:

public class Test {
    private Object o;

    public Test() {
        this.o = new Object();
    }

    private volatile static Test t;

    public static void createInstance() {
        t = new Test();             // volatile would insert memory barrier here.
    }

    public static void main(String[] args) throws Exception {
        Test.createInstance();
    }
}

そしてそれを逆コンパイルします:

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   new #2; //class java/lang/Object
   8:   dup
   9:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   12:  putfield    #3; //Field o:Ljava/lang/Object;
   15:  return

public static void createInstance();
  Code:
   0:   new #4; //class Test
   3:   dup
   4:   invokespecial   #5; //Method "<init>":()V
   7:   putstatic   #6; //Field t:LTest;
   10:  return

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   invokestatic    #7; //Method createInstance:()V
   3:   return

}

メモリバリアに関連するものは何も表示されず、削除しvolatileて再度逆コンパイルすると、バイトコードはまったく変更されません。

どうすればバイトコードで何かを見つけることができますか?

4

3 に答える 3

9

javap と適切なオプションでテストすると、フラグ ACC_VOLATILE が表示されます。

javap  -v -p Test

印刷:

 private static volatile Test t;
 flags: ACC_PRIVATE, ACC_STATIC, ACC_VOLATILE

(フラグは jvm 仕様Chapter 4. The class File Formatで定義されています)

于 2013-06-03T14:35:06.640 に答える
1

フィールドに追加volatileしても、フィールドを読み書きする Java バイトコードは変更されません。必要に応じて、JVM または JIT コンパイル出力によるプログラムの解釈のみを変更します。また、最適化にも影響します。

フィールド フラグ

読み取りと書き込みの同期

于 2013-06-03T14:04:38.997 に答える