2010-08-30 80 views
3

我的問題是爲什麼這行 - ThreadTest tt = new ThreadTest();在下面的例子中創建一個公共實例,而不是一個單獨的實例。請指教,謝謝!C#創建公共實例

class ThreadTest 
{ 
    bool done; 

    static void Main() 
    { 
    ThreadTest tt = new ThreadTest(); // Create a common instance 
    new Thread (tt.Go).Start(); 
    tt.Go(); 
    } 

    // Note that Go is now an instance method 
    void Go() 
    { 
    if (!done) { done = true; Console.WriteLine ("Done"); } 
    } 
} 

編輯: 的示例是從http://www.albahari.com/threading/#_Introduction,其演示瞭如何線程之間共享數據。

EDIT2: 我的問題就是爲什麼「的實例是常見的兩種線程」

+0

什麼是'ThreadTest'?我在框架中找不到這樣的類。 – Bobby 2010-08-30 09:53:18

+0

@Bobby:嗯,問題中的代碼聲明瞭它。 – Timwi 2010-08-30 09:54:09

+0

@Timwi:Doh,我是個白癡。 – Bobby 2010-08-30 09:56:51

回答

4

目前還不清楚你所說的「共同實例」的意思,但構造絕對創建一個新的實例。 Go方法執行兩次,一次在新線程中,一次在主線程中執行。

也許什麼代碼作者的意思是,實例是常見的兩個線程,因爲兩個線程調用同一實例Go方法。

Go方法的內部存在競爭條件。它可能無法預料地打印兩次「完成」。

+0

你的猜測是正確的。然而,我的問題正是爲什麼「這個實例對兩個線程都是共同的」。 – Stan 2010-08-30 09:59:45

+0

因爲您只創建一個並使用它兩次。 – Timwi 2010-08-30 10:10:06

+0

啊,我以爲它就像 new Thread(tt.Go).Start(); Go(); – Stan 2010-08-30 10:12:36

1

如果您的意思是這兩個調用tt.Go共享'完成'變量,那當然會發生。你在同一個對象上調用一個方法,只是在主線程中發生,而另一個發生在單獨的線程中。

你永遠只能創建ThreadTest的一個實例,但叫去了兩次,所以兩個調用具有相同的對象上發生!

1

6年後,我在這裏,因爲我讀了這本書的同一部分。在你剛剛提到的那本書之前的書中的例子顯示了(靜態的).Go在一個匿名的新線程上執行,然後在本地上下文中單獨執行。

new Thread (Go).Start(); 
Go(); 

的例子在你的問題首先創建TT的實例,也從一個靜態方法實例方法改變。去。

ThreadTest tt = new ThreadTest(); 
new Thread (tt.Go).Start(); 
tt.Go(); 

所以現在。去的時候被送到執行新的線程,結果收到了送什麼方法TT的拷貝(而不是靜態的。去的方法),這也是得到了什麼之後立即在本地執行因爲.Go的兩個執行都屬於tt,所以他們也使用tt的副本done。 Afaik,這就是爲什麼作者將這個數據稱爲「通用」,因爲它現在可以被兩個線程訪問。另外:我仍然在自己的幾個方面搖擺不定。我的一個謎團是什麼時候執行new Thread (tt.Go).Start(); ...... tt是在初始線程中實例化的,但它現在同時存在於兩者中? byref/byval在這裏適用還是其他事情正在進行?是否更準確地說,tt對象實際上不是「活着」或「屬於」任何線程,而是堆,因此兩個線程都應該可以訪問它?

+2

對於程序員來說,對象所有權對於技術來說更爲合理。該對象存在(生命)在堆上,沒有「所有者」。它是共享的,因爲在向新線程傳遞'tt.Go'時,它會捕獲'tt'實例,所以新線程引用'tt'確保它保持活動狀態;主線程也有對'tt'的引用。實際上,這提供了共享數據。對象在任何引用存在時都會存活 - 哪個線程或哪個線程無關緊要。 – MicroVirus 2016-06-11 00:46:25