2016-10-26 13 views
0

私のJavaコードは次のとおりです。私のJavaコードの出力は期待通りではありませんか?

public class TestVolatile { 

    static class Test { 
     int a = 0; 
     int b = 0; 
    } 

    public static void main(String[] args) { 

     for(int i=0;i<10000;i++) { 
      final Test test = new Test(); 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        test.a = 1; //test.a assignment before test.b assignment 
        test.b = 1; 
       } 
      }).start(); 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        System.out.println("a="+test.a+",b="+test.b); 
       } 
      }).start(); 
     } 
    } 
} 

java com.company.test_volatile.TestVolatile | sort -uですべての可能な出力を確認したいだけです。しかし、a=1, b=0がないと3つの結果しかありません。どんなに私は、コードを実行する回数

= 0、B = 0
= 0、B = 1
= 1、B = 1

、常に取得同じ結果。では、出力がない理由は何ですか?a=1, b=0printlnの同期はそれとは関係がありますか?

+3

スレッドインターリーブをルックアップします。 2つのスレッドが順番に開始されるため、同じ順序で実行することは保証されません。したがって、変数を設定するスレッドは、システムが印刷スレッドに切り替える前に9000回実行される可能性があります。または、出力に 'a = 0、b = 1'などの変数が1つ設定された後に発生する可能性があります。 – kjsebastian

+0

プログラムを実行しようとしましたが、77%a = 1、b = 1、23%a = 0 、b = 0、a = 0、b = 1、および_no_a = 1、b = 0というわずかな数の結果が得られます。したがって、これは実装とマシンに依存しているようです。 – ajb

+0

コードが何をしていると思いますか?あなたはそれをデバッガでステップスルーしたり、追加の出力を追加することができます。もっと。特定の、yoyは出力が期待通りではないと言いました。あなたは何を期待していますか? – David

答えて

0

私はそれをブルートフォースしなければなりませんでした。より良い方法があるかもしれません。私はa = 1、b = 0の出力を得ました。

$ for i in {1..1000}; do java TestVolatile | grep 'a=1,b=0'; done                         
a=1,b=0 
a=1,b=0 
a=1,b=0 
a=1,b=0 
a=1,b=0 

これはまだ進行中です。私がもっと得れば更新します

更新:私は1000 * 1000回から5試合を得ました。したがって、この出力の可能性は非常に低くなります。なぜそうなのか、私はそのマシンに依存していると思います。

+0

私はまだあなたのシェルコードを実行して出力を得ることができませんが、私はあなたが正しいと思います。 – dcnh35

+0

私の環境はunbuntuです。16.04 64bit、oracle jdk 18 – dcnh35

+0

ようやく私はそれを手に入れます。 – dcnh35