C# 線程同步與線程池 淺析

來源:互聯網
上載者:User
C# 線程同步與線程池

樣本很簡單,準備5個線程,每個線程同時向控制台輸出數字,然後觀察輸出結果。

代碼說明:

////線程列表

private static List<Thread> _threadList;          static voidMain(string[] args)        {            Program._threadList= new List<Thread>();            ////附加5個線程            for (inti = 0; i < 5; i++)            {                Program.AppendThread();            }             ////開始執行所有測試線程            Program.ExecuteThread();             ////按任意鍵退出            Console.ReadLine();        }         /// <summary>        /// 將新的測試線程附加到測試線程列表,線程執行邏輯就是輸出10個數字/// 注意初始化的時候設定為後台線程了,這樣可以保證主線程退出的時候其他線/// 程自動結束        /// </summary>        public staticvoid AppendThread()        {            Program._threadList.Add(newThread(new ThreadStart(                () =>                {                   for (int i = 0; i < 10; i++)                   {                       Console.WriteLine(i);                   }                })){ IsBackground = true });        }         /// <summary>        /// 開始執行所有測試線程        /// </summary>        public staticvoid ExecuteThread()        {            foreach(Thread t in _threadList)            {                t.Start();            }        }

觀察執行結果,我們可以看到結果如下:

根據結果(數位輸出是不規律的)可知,線程之間發生了幹擾。策略就是,加一個同步成員來進行線程同步:

   /// <summary>        /// 多線程同步的對象        /// </summary>        private static object _syncObj = new object();另外,線上程執行的地方加鎖:Program._threadList.Add(newThread(new ThreadStart(                () =>                {                    lock (_syncObj)                    {                        for (int i = 0; i < 10;i++)                        {                            Console.WriteLine(i);                        }                    }                 })) { IsBackground = true });

觀察結果:

可以看到通過Lock關鍵字,對一個多線程同步的變數加鎖的確可以使得線程同步。

現在看一下第二種方式:

使用monitor關鍵字進行同步,代碼:

Monitor.Enter(_syncObj);                   try                   {                       for (int i = 0; i < 10; i++)                       {                            Console.WriteLine(i);                       }                   }                   finally {                       Monitor.Exit(_syncObj);                   }

查看結果,會發現線程已經同步了。

第三種方式:

現在讓我們重構一下代碼,建立一個ThreadManager的類,把類的職責都搬進去:

class ThreadManager    {        /// <summary>        /// 線程列表        /// </summary>        private staticList<Thread> _threadList;         staticThreadManager()        {           _threadList = new List<Thread>();        }         /// <summary>        /// 附加新線程        /// </summary>        public staticvoid AppendThread()        {            ThreadManager._threadList.Add(newThread(new ThreadStart(                () =>                {                   for (int i = 0; i < 10; i++)                   {                       Console.WriteLine(i);                   }                 })){ IsBackground = true });        }         /// <summary>        /// 開始執行所有線程        /// </summary>        public staticvoid ExecuteThread()        {            foreach(Thread t in _threadList)            {                t.Start();            }        }    }

Main函數調用的代碼做相應的改變:

static voidMain(string[] args)        {            ////附加5個線程            for (int i = 0; i < 5; i++)            {                ThreadManager.AppendThread();            }             ////開始測試            ThreadManager.ExecuteThread();             ////按任意鍵繼續            Console.ReadLine();        }

由於沒有對線程同步做任何處理,結果肯定可以猜到,線程是不同步的:

現在對ThreadManager這個類加上特性:[Synchronization],再次運行之,發現線程同步了,這就是線程同步的第四種方案,用起來很簡單,但是首先它要求執行邏輯都放在一個類中,由於它可以確保這個類中的所有方法都是安全執行緒的,因此它的效能相對低效

線程同步還有方法嗎?答案是肯定的,那就是第四種方法—線程池。

現在來看一下如何用線程池來實現:

  static void Main(string[]args)        {/////定義一個waitCallback對象,並定義它的行為,就是向控制台輸出十個數字同時可以傳遞/////一個參數(這個參數是可選的)                       WaitCallback work = new WaitCallback((o)=>            {                for(int i = 0; i < 10; i++)                {                   Console.WriteLine(i);                }            });             ////執行5次            for (inti = 0; i < 5; i++)            {/////如果這裡需要傳遞參數,可以調用另一個重載方法                ThreadPool.QueueUserWorkItem(work);            }             ////按任意鍵繼續            Console.ReadLine();        }

這樣就完成了剛剛的邏輯嗎?是的,運行之後我們可以看到結果,線程是同步的。

多線程還帶來了哪些好處?

  • 線程池減少了線程建立、開始和停止的次數,從而提高了效率;

  • 使用線程池,能夠使我們將注意力放到商務邏輯上而不是多線程架構上(然而在某些情況應優先使用手工線程管理)

  • 如果需要前台線程或者設定優先權別,或者線程池中的線程總是後台線程,且他的優先順序是預設的;

  • 如果需要一個帶有固定標識的線程便於退出,掛起或通過名字發現它。

以上就是C# 線程同步與線程池 淺析的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.