天天看點

深入淺出多線程系列之一:簡單的Thread

CLR和作業系統會自動的為應用程式建立一個線程,這個線程叫做主線程(main Thread)

如果要建立一個新的線程,可以使用Thread類。下面是一個簡單的例子:

<a></a>

class ThreadTest

{

  static void Main()

  {

    Thread t = new Thread (WriteY);          // 建立一個新的線程來執行WriteY方法

    t.Start();                               // 開始運作 WriteY()

    //在主線程上模拟的做些事情. 

    for (int i = 0; i &lt; 1000; i++) Console.Write ("x");

  }

  static void WriteY()

    for (int i = 0; i &lt; 1000; i++) Console.Write ("y");

}

首先建立了一個線程來執行WriteY方法,然後調用Start()來啟動建立的線程,接着在主線程中用for循環輸出“x”。

很容易就知道答案:例如XXXXYYYYXXXXXYYYYYXXXXYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXX

X和y間隔的出現。

一旦線程啟動了,線程的IsAlive屬性線上程結束前就會傳回True,當傳遞給線程的構造函數中的委托執行完畢,線程就結束了,一旦線程結束了,線程是不可能再重新啟動的。

CLR為每一個線程配置設定獨立的記憶體棧,這樣就可以保證局部變量隔離。下面是使用局部變量的例子。

    {

        bool done;

        public static void Main()

        {

            ThreadTest tt = new ThreadTest();

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

            tt.Go();

        }

        void Go()

            if (!done)

            {

                done = true;

                Console.WriteLine("Done");

            }

    }

因為new Thread(tt.Go) 和tt.Go方法都共享tt的done字段。

是以Console.WriteLine("Done")會且隻會被執行一變。

我們修改下上面的代碼,修改後如下:

        static bool done; //靜态變量被所有的線程共享

            new Thread(Go).Start();

            Go();

        static void Go()

問題來了,Console.WriteLine會被執行幾遍?

有些同學會說一遍,有些同學會說兩遍,其實答案很簡單:有時候一遍,有時候兩遍。

因為靜态變量會被所有線程共享,

執行一遍的就不解釋了,比較簡單。

執行兩遍:線程A執行到if(!done) 此時done為false。是以通過if判斷,在同時線程B也執行到了if(!done)此時done也為false,是以也通過了判斷。

如果你把上面的Go代碼調整到下面的樣子,出現兩次的機率就會變大很多。

static void Go()

                //兩個線程都到了這裡

這種現象就叫做線程安全,或者說缺少線程安全。後續文章會慢慢介紹。

下面做下解釋: 

雖然new Thread(tt.Go) 和tt.Go方法都共享tt的done字段,但是兩個線程可能都通過了if判斷,

是以Console.WriteLine方法可能會被執行兩遍.

本文轉自LoveJenny部落格園部落格,原文連結:http://www.cnblogs.com/LoveJenny/archive/2011/05/21/2049300.html,如需轉載請自行聯系原作者

繼續閱讀