2017-10-19 6 views
-1

私は以下のコードを持っています。サンプル実行にJavaスレッドオブジェクトの操作が反映され、どのように?

public class Test implements Runnable 
{ 
    static int id = 0; 
    int value = 0; 
    public static int getId() { 
     return ++id; 
    } 

    public static void main(String[] args) 
    { 
     Test t = new Test(); 

     t.value = 10; 
     new Thread(t, "child " + getId()).start(); 
     new Thread(t, "child " + getId()).start(); 
     t.value = 20; 
     new Thread(t, "child " + getId()).start(); 
     new Thread(t, "child " + getId()).start(); 
    } 

    @Override 
    public void run() { 
     System.out.println("Thread " + Thread.currentThread().getName() + " started"); 
     System.out.println(Thread.currentThread().getName() + " Data - " + this.value); 
    } 
} 

出力:

Thread child 1 started 
Thread child 2 started 
child 2 Data - 20 
child 1 Data - 20 
Thread child 3 started 
child 3 Data - 20 
Thread child 4 started 
child 4 Data - 20 

私は、スレッドオブジェクトの(テスト)最新のデータがすべてのスレッドに反映されて見ることができました。しかしどうですか?

私は、t.value=20行の前に開始され、実行されたスレッドがデータ値 '10'を持つことを期待しています。私が間違っている?

答えて

0
new Thread(t, "child " + getId()).start();, 

は、この時点で新しいスレッドが開始されているわけではありません。それが始まるまでに時間がかかるかもしれません。 それを待つ場合は、それを変数に抽出することができます。

Thread t=new Thread(t, "child " + getId()); 
t.start(); 

、それが終了するのを待ちます。また、値20のデータを印刷する

t.join()はラッキーです、あなたのプログラムは、スレッドセーフではありませんので。あなたの例では、値の前に少なくともvolatileキーワードを使うべきです。

変数 valueが共有されているので、あなたはすべてのスレッドで同じ Runnableオブジェクトを渡す
volatile int value = 0; 
0

。表示される値は、スレッドが実行される順序によって異なります。メインスレッド(他のスレッドを作成しているスレッド)が最初に終了すると、この結果が表示されます。

0

スレッドを作成するときは、同じRunnable、つまりtを渡します。したがって、すべてのスレッドは同じvalueで効果的に動作します。

Thread.start()は、特定の発注を保証しません。スレッドは少し早くまたは少し遅れて開始することができます。スレッドが実行されるまでに、メインスレッドはすでにvalueを20に設定している可能性があります。

サイドノートとして、同期なしで共有変数を使用しています。予測可能な結果を​​得るには、volatileまたは​​を使用する必要があります。

関連する問題