日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

白話C#:多線程-.NET技術(shù)-dotnet技術(shù)

 ShangShujie 2010-05-06

作者:Autumoon 來源:博客園 酷勤網(wǎng)收集 2008-06-28

  使用多線程的時候常常需要考慮的并發(fā)問題,所以用了lock關(guān)鍵字,當一個線程要操作Contracts 時,它先把Contracts鎖起來,就是聲明一下:“現(xiàn)在我在操作它,你們誰都不要動,等我弄完了再說。”在lock塊結(jié)束時被鎖定的對象才會被解鎖, 其它線程才可以去操作它。
系列文章索引:《白話C#

多線程是程序員面試時常常會面對的問題,對多線程概念的掌握和理解水平,也會被一些老鳥用來衡量一個人的編程實力的重要參考指標。不論是實際工作需 要還是為了應(yīng)付面試,掌握多線程都是程序員職業(yè)生涯中一個必須經(jīng)過的環(huán)節(jié)。其實當你把“多線程”和你的“職業(yè)生涯”聯(lián)系在一起考慮的時候,就會覺得“多線 程”是多么的渺小,對,沒有跨越不過的山。不過就算它很渺小,但也有可能改變你的人生軌跡。不用擔(dān)心,如果你對多線程還不太熟悉,那么我們就一起來看看什 么是多線程吧。

跟前幾篇的風(fēng)格一樣,我會在開篇的時候舉一個現(xiàn)實生活中的例子,通過這個例子來映射一些晦澀枯燥的計算機編程專業(yè)知識,在讓讀者朋友很好地理解理論 概念的同時,又避免了閱讀教科書時的枯燥感覺。這次我要舉的例子是公司。不一定是IT公司,盡量和編程領(lǐng)域遠一點兒吧,那就假設(shè)是一家搬家公司吧。

假如我們把公司看做是一個進程,那么人就是其中的線程。進程必須得有一個主線程,公司在創(chuàng)業(yè)初期往往可能出現(xiàn)一人打天下的現(xiàn)象,但是,至少得有一個 人,公司才能運作。公司創(chuàng)業(yè)初期,業(yè)務(wù)還不算太多,往往就是老板一個人身兼數(shù)職,一天如果只有1、2趟活兒,應(yīng)該還是忙得過來的。時間長了,隨著業(yè)務(wù)的發(fā) 展、口碑地建立,生意越來越興隆,一個人肯定就忙不過來了。假設(shè)一天有5個活兒,老板一個人必須搬完A家才能搬B家,搬到黃昏估計也就搬到C家,D和E家 都還在焦急地等待著呢。老板一個人要充當搬運工、司機、業(yè)務(wù)聯(lián)系人、法人代表、出納等眾多角色,累死累活公司的規(guī)模也上不去,人手不夠制約了公司的發(fā)展。 那么怎么辦,很簡單,增加人手,用編程的話來說就是“再起個線程”。

 

我們現(xiàn)在就用代碼來描述這樣的場景吧,首先,我們準備成立一家搬家公司,于是要準備好將來和客戶簽的合同書:

   1: public class Contract
   2: {
   3:     public string ID { get; private set; }
   4:     public string From { get; set; }
   5:     public string To { get; set; }
   6:     public decimal Fee { get; set; }
   7:  
   8:     public Contract()
   9:     {
  10:         this.ID = DateTime.Now.ToBinary().ToString().Replace("-", String.Empty);
  11:     }
  12: }

 簡是簡單了點兒,好歹也是份合同,現(xiàn)在我們就去申請注冊一家公司,并組建好初創(chuàng)團隊,哪怕目前還只有老板一個人:

   1: public class HouseMovingCompany
   2: {
   3:     private static HouseMovingCompany _instance = null;
   4:     public static HouseMovingCompany Instance
   5:     {
   6:         get { return (_instance == null ? _instance = new HouseMovingCompany() : _instance); }
   7:     }
   8:  
   9:     public List<Contract> Contracts { get; private set; }
  10:  
  11:     public HouseMovingCompany()
  12:     {
  13:         this.Contracts = new List<Contract>();
  14:     }
  15:  
  16:     public void MoveHouse()
  17:     {
  18:         if (this.Contracts == null || this.Contracts.Count == 0)
  19:         {
  20:             return;
  21:         }
  22:  
  23:         Contract contract = contract = this.Contracts[0];
  24:         this.Contracts.RemoveAt(0);
  25:  
  26:         if (!String.IsNullOrEmpty(contract.From) && !String.IsNullOrEmpty(contract.To))
  27:         {
  28:             Console.WriteLine("Move the house from {0} to {1}.", contract.From, contract.To);
  29:         }
  30:  
  31:         Thread.Sleep(5000);
  32:     }
  33: }

好了,現(xiàn)在公司實體有了,老板就可以開始忙活了:

   1: static void Main(string[] args)
   2: {
   3:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "WuDaokou", To = "LinDa Road", Fee = 500 });
   4:  
   5:     while (HouseMovingCompany.Instance.Contracts.Count > 0)
   6:     {
   7:         HouseMovingCompany.Instance.MoveHouse();
   8:     }
   9: }

我們在前面設(shè)置了每次搬家耗時5秒鐘,咱們把它想象成5個小時。嗯,一天接一個單子,還可以接受,但是隨著老板生意日漸興隆,有時候一天要接3個單 子,這就最少要工作15個小時了,還要操心公司的運營等問題,的確忙不過來了,而且照這樣算,老板一天不可能完成5個或5個以上的單子,嚴重制約了公司的 發(fā)展:

   1: static void Main(string[] args)
   2: {
   3:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "WuDaokou", To = "LinDa Road", Fee = 500 });
   4:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "XiDan", To = "WangFujing", Fee = 1000 });
   5:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "XiangShan", To = "The Forbidden City", Fee = 10000 });
   6:  
   7:     while (HouseMovingCompany.Instance.Contracts.Count > 0)
   8:     {
   9:         HouseMovingCompany.Instance.MoveHouse();
  10:     }
  11: }

一天夜里,老板拖著疲倦的身子回到家里,一進門就一頭倒在床上,他極力睜著快睜不開的眼睛,努力地對自己說:“不行,我一定要想個辦法,不然我會被 累死的!”。

其實辦法很簡單,誰都知道,招聘幾個員工,再買幾輛車,大家分頭行動,不僅分擔(dān)了工作負擔(dān),而且在規(guī)模擴大的同時還可以完成更多更大的單子。好,我 們現(xiàn)在就借助多線程機制來實現(xiàn)我們的想法:

   1: static void Main(string[] args)
   2: {
   3:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "WuDaokou", To = "LinDa Road", Fee = 500 });
   4:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "XiDan", To = "WangFujing", Fee = 1000 });
   5:     HouseMovingCompany.Instance.Contracts.Add(new Contract { From = "XiangShan", To = "The Forbidden City", Fee = 10000 });
   6:  
   7:     Thread thread = null;
   8:  
   9:     while (HouseMovingCompany.Instance.Contracts.Count > 0)
  10:     {
  11:         thread = new Thread(new ThreadStart(HouseMovingCompany.Instance.MoveHouse));
  12:  
  13:         thread.Start();
  14:     }
  15: }

在這段程序中,我們分頭行動,讓每項搬家任務(wù)都由一個小團隊去完成,結(jié)果我們發(fā)現(xiàn),現(xiàn)在做三個單子的時間跟做一個單子的時間是一樣的,提高了效率也 擴大了公司規(guī)模。但是,既然引入了新的工作機制,我們在公司內(nèi)部也不得不做一些小小的調(diào)整:

   1: public void MoveHouse()
   2: {
   3:     if (this.Contracts == null || this.Contracts.Count == 0)
   4:     {
   5:         return;
   6:     }
   7:  
   8:     Contract contract = null;
   9:  
  10:     lock (this.Contracts)
  11:     {
  12:         contract = this.Contracts[0];
  13:         this.Contracts.RemoveAt(0);
  14:     }
  15:  
  16:     if (!String.IsNullOrEmpty(contract.From) && !String.IsNullOrEmpty(contract.To))
  17:     {
  18:         Console.WriteLine("Move the house from {0} to {1}.", contract.From, contract.To);
  19:     }
  20:  
  21:     Thread.Sleep(5000);
  22: }

調(diào)整的只是MoveHouse這個方法內(nèi)部的一些實現(xiàn)細節(jié)。公司接到的單子都保存在Contracts中,所以搬家的時候需要去拿一個單子然后根據(jù) 單子上的信息來工作。原先我們只有一個線程在操作Contracts,倒也不覺得什么,現(xiàn)在有多個線程都在對Contracts中的元素進行存取,我們不 得不提防一些意外發(fā)生。這就是在使用多線程的時候常常需要考慮的并發(fā)問題,所以我們用了lock關(guān)鍵字,當一個線程要操作Contracts時,它先把 Contracts鎖起來,其實就是聲明一下:“現(xiàn)在我在操作它,你們誰都不要動,等我弄完了再說。”在lock塊結(jié)束時被鎖定的對象才會被解鎖,其它的 線程現(xiàn)在才可以去操作它。

有了多線程機制,你會發(fā)現(xiàn)程序可以在更短的時間內(nèi)完成更多的事情。本文沒有將多線程機制中的所有概念面面俱到地列舉出來,但是已經(jīng)向你展示了該如何 使用多線程以及什么時候可以考慮使用多線程,其它的一些細節(jié)有待你去進一步探索,例如,你可以設(shè)置線程的優(yōu)先級(假設(shè)邏輯上跟Fee掛鉤,類似于‘加 急’)等等。

掌握多線程機制,并讓它使你的應(yīng)用程序變得更加強悍吧。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多