C# 線程理解


概念引用:http://blog.csdn.net/yujie_yang/article/details/53173752

多線程和多進程的區別:任務管理器里各種不同的進程就是多進程,或者是你同時運行多個”.exe’程序就可以理解為多進程,多進程是要更多消耗CPU資源的。 
多線程是相對於進程里更小的單位,比如3個線程在1個進程里進行不同的操作,他們所擁有的資源就是那個進程里的資源,不會占用更多資源,只是通過線程更合理的分配資源。 

一.單線程 
在很久以前的MS-DOS時代時代,都是單任務的,比如說我想玩潛艇大戰和聽歌,很抱歉,只能選擇玩潛艇大戰或者聽歌,不能同時進行。 
所以我只能先玩潛艇大戰,玩膩了就關掉游戲打開音樂播放器聽一首《七里香》來舒緩心緒,模擬的程序如下:

 public static void game() { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff") + " 玩潛艇大戰"); } public static void music() { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff") + " 聽七里香"); } static void Main(string[] args) { game(); music(); Console.ReadKey(); }


我們控制台輸出的結果為: 
2016-11-15 04:30:56.724 玩潛艇大戰 
2016-11-15 04:30:56.755 聽七里香

二.雙線程 
當然,我們現在的時代大可不必那么老實的先干什么再干什么,我們可以選擇邊玩游戲,邊聽歌。模擬代碼如下:

public static void game() { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff") + " 玩潛艇大戰"); } public static void music() { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff") + " 聽七里香"); } static void Main(string[] args) { Thread t1 = new Thread(new ThreadStart(game));//開始一個玩游戲的線程 Thread t2 = new Thread(new ThreadStart(music));//開始一個聽音樂的線程 t1.Start(); t2.Start(); Console.ReadKey(); }

控制台輸出結果為: 
2016-11-15 04:43:48.987 玩潛艇大戰 
2016-11-15 04:43:48.988 聽七里香

2016-11-15 04:45:19.315 聽七里香 
2016-11-15 04:45:19.315 玩潛艇大戰

2016-11-15 04:46:38.513 聽七里香 
2016-11-15 04:46:38.512 玩潛艇大戰 
這三組結果可以看出,運用線程后玩游戲和聽音樂可以同時展開,兩個任務不分先后時間差明顯比單線程模式要少,更合理的利用了資源。

 

三.三線程 
其實以上的代碼中還隱藏了一個線程,就是主線程Main(string[] args),我們下面再改進一下代碼看看三個線程運行時的情況。 
核心代碼更改如下:

static void Main(string[] args)
        {
            Thread t1 = new Thread(new ThreadStart(game));//開始一個玩游戲的線程 Thread t2 = new Thread(new ThreadStart(music));//開始一個聽音樂的線程 t1.Priority = ThreadPriority.BelowNormal; t2.Priority = ThreadPriority.Lowest; t1.Start(); t2.Start(); Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff") +" 邊玩游戲邊聽音樂"); Console.ReadKey(); }

控制台輸出結果: 
2016-11-15 05:01:15.598 聽七里香 
2016-11-15 05:01:15.575 邊玩游戲邊聽音樂 
2016-11-15 05:01:15.598 玩潛艇大戰

2016-11-15 05:03:25.966 聽七里香 
2016-11-15 05:03:25.964 邊玩游戲邊聽音樂 
2016-11-15 05:03:25.965 玩潛艇大戰

2016-11-15 05:03:50.022 聽七里香 
2016-11-15 05:03:50.001 邊玩游戲邊聽音樂 
2016-11-15 05:03:50.001 玩潛艇大戰

 

不知道大家注意到沒有,主線程每次都是先執行的,並且聽音樂好像也總是比玩游戲要晚執行,因為代碼里我有一個改動:

            t1.Priority = ThreadPriority.BelowNormal; t2.Priority = ThreadPriority.Lowest;

沒錯,我設置了線程的優先級,t2代表聽音樂的線程優先級比t1玩游戲的優先級要低。對應現實來說就好像我要先打開游戲玩着玩着覺得配樂不好聽,所以我選擇靜音再點開我最愛的《七里香》,這樣玩游戲就更加帶勁了!

 

四.線程的優先級 
線程的優先級可以通過Thread類Priority屬性設置,Priority屬性是一個ThreadPriority型枚舉,列舉了5個優先等級:AboveNormal、BelowNormal、Highest、Lowest、Normal。普通線程的優先級默認為Normal;如果想有更高的優先級,可設置為AboveNormal或Highest;如果想有較低的優先級,可設置為BelowNormal或Lowest。 
也許有人會問那之前的例子主線程總是先完成是不是優先級默認要高呢?其實不是的,主線程和工作線程的優先級相同,也是交替進行,被執行的概率大體相同,至於每次先完成是因為主線程會先啟動,只有啟動了主線程才能開啟其他工作線程。 
要注意的是:系統優先執行優先級較高的線程,但這只意味着優先級較高的線程占有更多的CPU時間,並不意味着一定要先執行完優先級較高的線程,才會執行優先級較低的線程。

 

五.多線程同步

對多線程進行同步,主要用到的是MethodImplAttribute 類 和 SynchronizationAttribute 類,本質上還是基於Lock的實現的。

一個簡單如小明和小紅兩個人用都是主附銀行卡,兩個人都可以對帳戶進行操作,比如帳戶余額1000元,比如兩個人幾乎同時進行取錢600元的操作。

引入MethodImplAttribute 類:

在使用 MethodImplAttribute 類之前需要引用 System.Runtime.Remoting.Contexts 命名空間,System.Runtime.Remoting.Contexts 命名空間包含的一些屬性將影響CLR 在運行期間的行為,MethodImplAttribute 就是這樣一個屬性,MethodImplAttribute類的一個構造函數把MethodImplOptions枚舉作為其參數,MethodImplOptions 枚舉有一個字段Synchronized,,它指定在任一時刻只允許一個線程訪問這個方法。

 

具體參考詳解連接  http://www.cnblogs.com/miniwiki/archive/2010/06/18/1760540.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM