2017-10-19 21 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 

我可以看到線程對象的(測試)最新公佈的數據反映在所有的線程。但是如何?

我期待該線程開始,並應具有數據值「10」行t.value=20之前執行。我錯了嗎?

回答

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

並不意味着,這個新的線程開始在這一刻。開始之前可能需要一些時間。 如果你想等待它,你可以將它提取到一個變量。

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

,並等待其完成:t.join()

而且打印的值20的數據是幸運的,因爲你的程序是不是線程安全的。在你的例子中,你應該至少在值前使用volatile關鍵字。

volatile int value = 0; 
0

您越過同一Runnable對象的所有線程,以便可變value是共享的。您看到的值取決於線程執行的順序。如果主線程(創建其他線程的線程)首先完成,您將看到此結果。

0

當你創建線程,你將它們同Runnable,那就是t。所以所有的線程都可以有效地使用相同的value

Thread.start()不保證任何特定的順序。線程可以稍早或稍後開始。當線程有機會運行時,您的主線程可能已將value設置爲20.

作爲便箋:您正在使用共享變量而沒有任何同步。您應該使用volatile或​​以獲得可預測的結果。