2011-04-04 135 views
1

我走的Java課程。我們現在進入線程。這是我第一次經歷了多線程,所以請原諒我,如果這個問題是非常愚蠢的:)Java線程問題

我下面的程序:

public class Foo extends Thread { 
    private int x = 2; 

    public static void main(String[]args) { 
     new Foo().fun(); 
    } 

    Foo() { 
     x = 5; 
     start(); 
    } 

    public void fun() { 
     x = x - 1; 
     System.out.println(x); 
    } 
    public void run() { 
     x = x * 2; 
    } 
} 

當我運行該程序,我得到4作爲輸出。上述程序的輸出是否總是4?

+0

這是功課? – 2011-04-04 16:36:55

+0

我的文本有這個練習,但不是作業。 – user691451 2011-04-04 16:39:05

回答

-2

是的,它永遠是4,我看不出有任何理由豈不是4

你只運行fun()永不run()

閱讀java Thread man

+3

但構造函數正在調用啓動哪個調用運行。 – user691451 2011-04-04 16:35:14

+0

是的,但永遠不會將它實例化爲線程 – Neal 2011-04-04 16:36:34

+0

沒有什麼特別的事情可以實例化一個'Thread',只需像常規類一樣調用'new'即可。你引用的Javadoc也是一個例子。 – 2011-04-04 16:41:27

4

它不會永遠是4

如果Foo run()方法在主線程運行fun()之前執行,它將爲9.

如果富的run()方法執行,而主要是運行的樂趣(),這將是8

如果main()的結束符開始之前,這將是4

+0

很酷。謝謝。你能解釋一下「8作爲輸出」的部分嗎? – user691451 2011-04-04 16:36:43

+1

我明白了。如果x = x * 2發生在x = 5之後但在打印之前。我對嗎 ? – user691451 2011-04-04 16:40:52

+0

值得注意的是,因爲線程是在構造函數中啓動的,所以線程可以將'x'看作5,2或0(或4在fun()開始後啓動) – 2011-04-04 16:55:19

2

不,並非總是如此。因爲在構造函數你打電話start()方法,有一個從主線程調用funrun將的x值從Thread.start改變之間的競爭條件。

但是,實際上,如果沒有正確的同步,那麼將不會保證輸出是什麼,與調用funrun的順序無關。由於同步確保更改線程知名度,輸出可以是4即使run將完成前fun被調用。

+0

謝謝你的先生。這個網站太快了:) – user691451 2011-04-04 16:38:03

0

正如你說你正在學習多線程,你必須知道,你永遠無法預知不同的線程的執行順序。

這是一個非常簡單的程序,其中主線程將幾乎總是第一個完成 - 但要記住重要的一點是,你永遠無法確定在複雜的多線程場景。實際上,當一個線程不依賴於另一個線程的執行時,您主要選擇多線程方法。

BTW嘗試改變的構造是這樣的:

Foo() { 
     x = 5; 
     start(); 
     Thread.sleep(2 * 1000); 
    } 

,你可能會得到不同的結果。

0

Simon's answer是正確的一個警告。 Java有一些變量值的緩存。如果一個變量沒有被設置爲volatile,或者如果你不使用原子值,你可能會得到緩存的值而不是最新的值。