版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1 1第第2章章 進(jìn)程與線程進(jìn)程與線程2.1 進(jìn)程與線程的基本概念進(jìn)程與線程的基本概念2.2 進(jìn)程管理(進(jìn)程管理(Process類)類)2.3 線程管理(線程管理(Thread類)類)2.4 線程同步與線程池線程同步與線程池2.5 BackgroundWorker組件組件2 2本章重點(diǎn)本章重點(diǎn)本章教學(xué)目的本章教學(xué)目的 通過(guò)對(duì)進(jìn)程、線程基本知識(shí)以及通過(guò)對(duì)進(jìn)程、線程基本知識(shí)以及BackgroundWorker組件組件的介紹,使學(xué)生對(duì)相關(guān)內(nèi)容有一個(gè)感性認(rèn)識(shí)。的介紹,使學(xué)生對(duì)相關(guān)內(nèi)容有一個(gè)感性認(rèn)識(shí)。本章教學(xué)要求本章教學(xué)要求(1)掌握進(jìn)程查看、啟動(dòng)、停止的基本方法;)掌握進(jìn)程查看、啟動(dòng)、停止的基本方法;
2、(2)掌握線程創(chuàng)建、啟動(dòng)、終止的基本方法;)掌握線程創(chuàng)建、啟動(dòng)、終止的基本方法;(3)掌握開(kāi)辟多線程的基本方法;)掌握開(kāi)辟多線程的基本方法;(4)掌握在一個(gè)線程中引用其他線程中的控件的方法;)掌握在一個(gè)線程中引用其他線程中的控件的方法;(5)了解其他內(nèi)容。)了解其他內(nèi)容。3 32.1 進(jìn)程與線程的基本概念進(jìn)程與線程的基本概念 進(jìn)程進(jìn)程 正在執(zhí)行的程序稱為進(jìn)程。正在執(zhí)行的程序稱為進(jìn)程。 與進(jìn)程相關(guān)的信息包括:進(jìn)程標(biāo)識(shí)(進(jìn)程與進(jìn)程相關(guān)的信息包括:進(jìn)程標(biāo)識(shí)(進(jìn)程ID)、文件名、執(zhí))、文件名、執(zhí)行的程序和數(shù)據(jù),運(yùn)行時(shí)間、在存儲(chǔ)器中的位置、占用的內(nèi)行的程序和數(shù)據(jù),運(yùn)行時(shí)間、在存儲(chǔ)器中的位置、占用的內(nèi)存容
3、量等。存容量等。 線程線程 將一個(gè)進(jìn)程劃分為若干個(gè)獨(dú)立的執(zhí)行流,每一個(gè)執(zhí)行流均稱將一個(gè)進(jìn)程劃分為若干個(gè)獨(dú)立的執(zhí)行流,每一個(gè)執(zhí)行流均稱為一個(gè)線程。為一個(gè)線程。 (1)線程是)線程是CPU調(diào)度和分配的基本單位。調(diào)度和分配的基本單位。 (2)每個(gè)進(jìn)程都有一個(gè))每個(gè)進(jìn)程都有一個(gè)主線程主線程。 (3)除了主線程以外,還可以給一個(gè)進(jìn)程分配若干個(gè)子線程,)除了主線程以外,還可以給一個(gè)進(jìn)程分配若干個(gè)子線程,從而達(dá)到多個(gè)任務(wù)并行執(zhí)行的目的。從而達(dá)到多個(gè)任務(wù)并行執(zhí)行的目的。4 42.2 進(jìn)程管理(進(jìn)程管理(Process類)類)1、Process類位于類位于System.Diagnostics命名空間下。命名空間
4、下。2、對(duì)本機(jī)(也叫本地計(jì)算機(jī))、對(duì)本機(jī)(也叫本地計(jì)算機(jī)) (1)可以啟動(dòng)、終止某個(gè)進(jìn)程)可以啟動(dòng)、終止某個(gè)進(jìn)程 (2)可以查看進(jìn)程相關(guān)信息,如)可以查看進(jìn)程相關(guān)信息,如CPU利用率等利用率等 (3)可以查看進(jìn)程工作狀態(tài))可以查看進(jìn)程工作狀態(tài)3、對(duì)遠(yuǎn)程計(jì)算機(jī)、對(duì)遠(yuǎn)程計(jì)算機(jī) (1)可以查看遠(yuǎn)程計(jì)算機(jī)相關(guān)信息)可以查看遠(yuǎn)程計(jì)算機(jī)相關(guān)信息 (2)無(wú)法直接啟動(dòng)、終止遠(yuǎn)程計(jì)算機(jī))無(wú)法直接啟動(dòng)、終止遠(yuǎn)程計(jì)算機(jī)4、在一個(gè)程序中處理其他的程序(例如調(diào)用其他、在一個(gè)程序中處理其他的程序(例如調(diào)用其他.exe文件、文件、 快捷方式等),實(shí)際上就是對(duì)進(jìn)程進(jìn)行管理??旖莘绞降龋?,實(shí)際上就是對(duì)進(jìn)程進(jìn)行管理。5 52.2
5、 進(jìn)程管理(進(jìn)程管理(Process類)類) Process類提供的靜態(tài)方法類提供的靜態(tài)方法6 62.2 進(jìn)程管理(進(jìn)程管理(Process類)類)5、Process類常用的屬性和方法類常用的屬性和方法-獲取進(jìn)程實(shí)例獲取進(jìn)程實(shí)例-uGetProcessById方法(靜態(tài)方法):通過(guò)進(jìn)程方法(靜態(tài)方法):通過(guò)進(jìn)程Id創(chuàng)建創(chuàng)建新的新的Process組件,并將其與本地計(jì)算機(jī)上的進(jìn)程資源組件,并將其與本地計(jì)算機(jī)上的進(jìn)程資源關(guān)聯(lián)。關(guān)聯(lián)。 GetProcessById最多只有一個(gè)最多只有一個(gè)Process實(shí)例。實(shí)例。uGetProcesses方法(靜態(tài)方法):獲取本機(jī)所有進(jìn)程方法(靜態(tài)方法):獲取本機(jī)所有
6、進(jìn)程uGetProcessesByName方法(靜態(tài)方法):獲取本機(jī)方法(靜態(tài)方法):獲取本機(jī)上特定名稱的進(jìn)程上特定名稱的進(jìn)程-獲取及設(shè)置優(yōu)先級(jí)獲取及設(shè)置優(yōu)先級(jí)-uBasePriority屬性屬性: 獲取進(jìn)程優(yōu)先級(jí)(只讀)獲取進(jìn)程優(yōu)先級(jí)(只讀)uPriorityClass 屬性:設(shè)置或更改進(jìn)程優(yōu)先級(jí)屬性:設(shè)置或更改進(jìn)程優(yōu)先級(jí)7 72.2 進(jìn)程管理(進(jìn)程管理(Process類)類)-進(jìn)程進(jìn)程ID及進(jìn)程名及進(jìn)程名-uId屬性:獲取關(guān)聯(lián)進(jìn)程的屬性:獲取關(guān)聯(lián)進(jìn)程的唯一標(biāo)識(shí)符唯一標(biāo)識(shí)符uProcessName屬性:獲取進(jìn)程的名稱,不包括路徑和擴(kuò)展名屬性:獲取進(jìn)程的名稱,不包括路徑和擴(kuò)展名 -進(jìn)程其他信息
7、進(jìn)程其他信息-uMachineName屬性:獲取關(guān)聯(lián)進(jìn)程正在其上運(yùn)行的計(jì)算機(jī)名屬性:獲取關(guān)聯(lián)進(jìn)程正在其上運(yùn)行的計(jì)算機(jī)名uMainModule屬性:獲取關(guān)聯(lián)進(jìn)程的主模塊屬性:獲取關(guān)聯(lián)進(jìn)程的主模塊uModules屬性:獲取由關(guān)聯(lián)進(jìn)程加載的模塊屬性:獲取由關(guān)聯(lián)進(jìn)程加載的模塊uTotalProcessorTime屬性:獲取進(jìn)程的總的處理器時(shí)間屬性:獲取進(jìn)程的總的處理器時(shí)間uStartTime屬性:獲取關(guān)聯(lián)進(jìn)程的啟動(dòng)時(shí)間屬性:獲取關(guān)聯(lián)進(jìn)程的啟動(dòng)時(shí)間uWorkingSet64屬性:為進(jìn)程分配的物理內(nèi)存量(字節(jié)數(shù))屬性:為進(jìn)程分配的物理內(nèi)存量(字節(jié)數(shù))8 81.2 Process類類-進(jìn)程啟動(dòng)進(jìn)程啟動(dòng)-uS
8、tart方法:?jiǎn)?dòng)進(jìn)程資源并將其與方法:?jiǎn)?dòng)進(jìn)程資源并將其與Process組件關(guān)聯(lián)組件關(guān)聯(lián)uStartInfo屬性:獲取或設(shè)置要傳遞給啟動(dòng)進(jìn)程的文件名屬性:獲取或設(shè)置要傳遞給啟動(dòng)進(jìn)程的文件名以及啟動(dòng)參數(shù)以及啟動(dòng)參數(shù)-進(jìn)程終止進(jìn)程終止-uKill方法:強(qiáng)制終止進(jìn)程方法:強(qiáng)制終止進(jìn)程uCloseMainWindow方法:關(guān)閉具有用戶界面的進(jìn)程方法:關(guān)閉具有用戶界面的進(jìn)程uClose方法:釋放與此組件關(guān)聯(lián)的所有資源方法:釋放與此組件關(guān)聯(lián)的所有資源uHasExited屬性:指示關(guān)聯(lián)進(jìn)程是否已終止屬性:指示關(guān)聯(lián)進(jìn)程是否已終止uWaitForExit方法:設(shè)置等待關(guān)聯(lián)進(jìn)程退出的時(shí)間,并在方法:設(shè)置等待關(guān)聯(lián)
9、進(jìn)程退出的時(shí)間,并在該段時(shí)間結(jié)束前或該進(jìn)程退出前,阻止當(dāng)前線程執(zhí)行。該段時(shí)間結(jié)束前或該進(jìn)程退出前,阻止當(dāng)前線程執(zhí)行。9 92.2.1 獲取進(jìn)程信息獲取進(jìn)程信息1、如何獲取進(jìn)程信息、如何獲取進(jìn)程信息(1)獲取本地計(jì)算機(jī)的所有進(jìn)程:)獲取本地計(jì)算機(jī)的所有進(jìn)程: Process myProcesses = Process.GetProcesses();(2)獲取本地計(jì)算機(jī)上指定名稱的進(jìn)程:)獲取本地計(jì)算機(jī)上指定名稱的進(jìn)程: Process myProcesses = Process.GetProcessesByName(進(jìn)程名稱進(jìn)程名稱); 注意:(注意:(a)進(jìn)程名稱不帶擴(kuò)展名。)進(jìn)程名稱不帶擴(kuò)展
10、名。 (b)可以是任何一個(gè)可執(zhí)行文件)可以是任何一個(gè)可執(zhí)行文件例如:例如: Process myProcesses = Process.GetProcessesByName (“notepad);10102.2.1 獲取進(jìn)程信息獲取進(jìn)程信息(續(xù))(續(xù))(3)獲取遠(yuǎn)程計(jì)算機(jī)的所有進(jìn)程:)獲取遠(yuǎn)程計(jì)算機(jī)的所有進(jìn)程: Process myProcesses = Process.GetProcesses (remoteMachineName); 例如:例如: Process myProcesses = Process.GetProcesses ();(4)獲取遠(yuǎn)程計(jì)算機(jī)上指定名稱
11、的進(jìn)程:)獲取遠(yuǎn)程計(jì)算機(jī)上指定名稱的進(jìn)程: Process myProcesses = Process.GetProcessesByName( 遠(yuǎn)程進(jìn)程名稱遠(yuǎn)程進(jìn)程名稱,remoteMachineName);1111程序舉例程序舉例【例例2-1】【例例2-1】觀察本機(jī)運(yùn)行的所有進(jìn)程,并顯示進(jìn)程相關(guān)的信觀察本機(jī)運(yùn)行的所有進(jìn)程,并顯示進(jìn)程相關(guān)的信息。息。 要求:要求: (1)用)用DataGridView顯示所有進(jìn)程信息顯示所有進(jìn)程信息 (2)鼠標(biāo)單擊)鼠標(biāo)單擊DataGridView某處時(shí),判斷單擊的是否為某處時(shí),判斷單擊的是否為行開(kāi)頭或者某個(gè)單元格,如果是,顯示該行進(jìn)程的詳細(xì)行開(kāi)頭或者某個(gè)單元
12、格,如果是,顯示該行進(jìn)程的詳細(xì)信息信息 (運(yùn)行效果見(jiàn)下頁(yè)圖)(運(yùn)行效果見(jiàn)下頁(yè)圖)12121.2.1 獲取進(jìn)程信息獲取進(jìn)程信息(續(xù))(續(xù))運(yùn)行效果(運(yùn)行效果(ProcessMonitor):):13132.2.2 啟動(dòng)和停止進(jìn)程啟動(dòng)和停止進(jìn)程1. 啟動(dòng)進(jìn)程:?jiǎn)?dòng)進(jìn)程:方法方法1:(1)創(chuàng)建一個(gè))創(chuàng)建一個(gè)Process組件的實(shí)例,例如:組件的實(shí)例,例如: Process p = new Process();(2)設(shè)置其對(duì)應(yīng)的)設(shè)置其對(duì)應(yīng)的StartInfo屬性,指定要運(yùn)行的應(yīng)用程序名以及屬性,指定要運(yùn)行的應(yīng)用程序名以及傳遞的參數(shù):傳遞的參數(shù): p.StartInfo.FileName = 文件名文
13、件名; p.StartInfo.Arguments = 參數(shù)參數(shù); 如果該進(jìn)程帶有圖形用戶界面,也可以指定圖形用戶界面的打如果該進(jìn)程帶有圖形用戶界面,也可以指定圖形用戶界面的打開(kāi)方式。例如:開(kāi)方式。例如: p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;(3)調(diào)用該實(shí)例的)調(diào)用該實(shí)例的Start方法啟動(dòng)該進(jìn)程。方法啟動(dòng)該進(jìn)程。14142.2.2 啟動(dòng)和停止進(jìn)程啟動(dòng)和停止進(jìn)程1. 啟動(dòng)進(jìn)程:?jiǎn)?dòng)進(jìn)程: 方法方法2:直接調(diào)用直接調(diào)用Process類提供的類提供的Start靜態(tài)方法啟動(dòng)進(jìn)程。靜態(tài)方法啟動(dòng)進(jìn)程。進(jìn)程啟動(dòng)舉例:進(jìn)程啟動(dòng)舉例:1515
14、2.2.2 啟動(dòng)和停止進(jìn)程(續(xù))啟動(dòng)和停止進(jìn)程(續(xù))2. 停止進(jìn)程停止進(jìn)程 停止進(jìn)程的方法有兩種。停止進(jìn)程的方法有兩種。(1)如果進(jìn)程有圖形用戶界面,調(diào)用)如果進(jìn)程有圖形用戶界面,調(diào)用Process類提供的類提供的CloseMainWindow方法。方法。(2)如果進(jìn)程沒(méi)有用戶界面,調(diào)用)如果進(jìn)程沒(méi)有用戶界面,調(diào)用Process類提供的類提供的Kill方法。方法。 不論進(jìn)程有沒(méi)有圖形用戶界面,如果希望強(qiáng)行讓其退不論進(jìn)程有沒(méi)有圖形用戶界面,如果希望強(qiáng)行讓其退出,在權(quán)限允許的情況下,均可以調(diào)用出,在權(quán)限允許的情況下,均可以調(diào)用Kill方法終止該方法終止該進(jìn)程。進(jìn)程。 注意:若進(jìn)程正要終止的同時(shí)調(diào)用
15、注意:若進(jìn)程正要終止的同時(shí)調(diào)用Kill方法,可能會(huì)引方法,可能會(huì)引發(fā)異常,所以調(diào)用時(shí)最好使用發(fā)異常,所以調(diào)用時(shí)最好使用try/catch語(yǔ)句。語(yǔ)句。1616程序舉例程序舉例【例例2-2】【例例2-2】啟動(dòng)、停止和觀察啟動(dòng)、停止和觀察Notepad進(jìn)程。進(jìn)程。(StartStopProcess)要求:)要求:(1)用)用ListView顯示顯示“記事本記事本”進(jìn)程信息。進(jìn)程信息。(2)用)用Process類提供的實(shí)例方法啟動(dòng)進(jìn)程。類提供的實(shí)例方法啟動(dòng)進(jìn)程。(3)終止進(jìn)程時(shí),把所有)終止進(jìn)程時(shí),把所有“記事本記事本”進(jìn)程全部終止。進(jìn)程全部終止。1717擴(kuò)充實(shí)驗(yàn)擴(kuò)充實(shí)驗(yàn)【簡(jiǎn)易任務(wù)管理器開(kāi)發(fā)】【簡(jiǎn)易任
16、務(wù)管理器開(kāi)發(fā)】界面設(shè)計(jì)和開(kāi)發(fā)要點(diǎn):界面設(shè)計(jì)和開(kāi)發(fā)要點(diǎn): (1)ListView控件(列的定義、顯示方式選擇)控件(列的定義、顯示方式選擇) (2)NotifyIcon控件(最小化顯示圖標(biāo)、界面還原顯示)控件(最小化顯示圖標(biāo)、界面還原顯示) (3)Process類提供的屬性和方法(進(jìn)程啟動(dòng)、終止、進(jìn)程相類提供的屬性和方法(進(jìn)程啟動(dòng)、終止、進(jìn)程相關(guān)信息的獲得)關(guān)信息的獲得)1818項(xiàng)目中的應(yīng)用:在程序中執(zhí)行項(xiàng)目中的應(yīng)用:在程序中執(zhí)行sql文件文件說(shuō)明:說(shuō)明:osql.exe是是SQL Server提供的一個(gè)工具,可以利用該工提供的一個(gè)工具,可以利用該工具添加、刪除數(shù)據(jù)庫(kù)用戶,修改用戶登錄密碼,附加
17、、分離具添加、刪除數(shù)據(jù)庫(kù)用戶,修改用戶登錄密碼,附加、分離數(shù)據(jù)庫(kù)等。對(duì)于通過(guò)程序管理數(shù)據(jù)庫(kù)很有用。數(shù)據(jù)庫(kù)等。對(duì)于通過(guò)程序管理數(shù)據(jù)庫(kù)很有用。public void ExecuteSqlFile(string strFileName) Process SqlProcess=new Process(); SqlProcess.StartInfo.FileName=osql.exe; SqlProcess.StartInfo.Arguments=-U sa -P sa123 -d mydb -i+ strFileName; SqlProcess.StartInfo.WindowStyle= Proce
18、ssWindowStyle.Hidden; SqlProcess.Start(); SqlProcess.WaitForExit(); SqlProcess.Close(); 19192.3 線程管理(線程管理(Thread類)類) 2.3.1 前臺(tái)線程與后臺(tái)線程前臺(tái)線程與后臺(tái)線程 2.3.2 線程基本操作線程基本操作 2.3.3 Volatile關(guān)鍵字關(guān)鍵字 2.3.4 在一個(gè)線程中操作另一個(gè)線程的控件在一個(gè)線程中操作另一個(gè)線程的控件20202.3 線程管理(線程管理(Thread類)類) Thread類位于類位于System.Threading命名空間下。命名空間下。 Thread類是用于
19、創(chuàng)建和控制線程的類是用于創(chuàng)建和控制線程的,對(duì)線程的常用操作對(duì)線程的常用操作有:?jiǎn)?dòng)線程、終止線程、合并線程和讓線程休眠等。有:?jiǎn)?dòng)線程、終止線程、合并線程和讓線程休眠等。 Thread類提供的常用屬性類提供的常用屬性u(píng) IsAlive屬性屬性:獲取一個(gè)值,該值指示當(dāng)前線程的執(zhí)行:獲取一個(gè)值,該值指示當(dāng)前線程的執(zhí)行狀態(tài)。如果此線程已啟動(dòng)并且尚未正常終止,則為狀態(tài)。如果此線程已啟動(dòng)并且尚未正常終止,則為true;否則為否則為falseu IsBackground屬性屬性:獲取或設(shè)置一個(gè)值,該值指示某獲取或設(shè)置一個(gè)值,該值指示某個(gè)線程是否為后臺(tái)線程。是后臺(tái)線程或即將成為后臺(tái)線個(gè)線程是否為后臺(tái)線程。是
20、后臺(tái)線程或即將成為后臺(tái)線程,則為程,則為true;否則為;否則為false1. Priority屬性:屬性:獲取或設(shè)置一個(gè)值,該值指示線程的調(diào)獲取或設(shè)置一個(gè)值,該值指示線程的調(diào)度優(yōu)先級(jí)度優(yōu)先級(jí)21212.3 線程管理(線程管理(Thread類)(續(xù))類)(續(xù)) Thread類提供的常用方法類提供的常用方法u Start方法方法:?jiǎn)?dòng)線程:?jiǎn)?dòng)線程u Join方法:方法:將指定的線程合并到當(dāng)前線程中,并阻止當(dāng)將指定的線程合并到當(dāng)前線程中,并阻止當(dāng)前線程執(zhí)行,直到指定的線程終止或經(jīng)過(guò)了指定的時(shí)間為前線程執(zhí)行,直到指定的線程終止或經(jīng)過(guò)了指定的時(shí)間為止止u Sleep方法:方法:將當(dāng)前線程阻止指定的毫
21、秒數(shù),零將當(dāng)前線程阻止指定的毫秒數(shù),零(0)表示應(yīng)表示應(yīng)掛起此線程以使其他等待線程能夠執(zhí)行掛起此線程以使其他等待線程能夠執(zhí)行1. Abort方法:方法:在調(diào)用此方法的線程上引發(fā)在調(diào)用此方法的線程上引發(fā)ThreadAbortException,以開(kāi)始終止此線程的過(guò)程。調(diào),以開(kāi)始終止此線程的過(guò)程。調(diào)用此方法通常會(huì)終止線程用此方法通常會(huì)終止線程22222.3.1 前臺(tái)線程與后臺(tái)線程前臺(tái)線程與后臺(tái)線程一個(gè)線程要么是后臺(tái)線程要么是前臺(tái)線程。一個(gè)線程要么是后臺(tái)線程要么是前臺(tái)線程。后臺(tái)線程與前臺(tái)線程類似,區(qū)別是后臺(tái)線程不會(huì)影響進(jìn)后臺(tái)線程與前臺(tái)線程類似,區(qū)別是后臺(tái)線程不會(huì)影響進(jìn)程終止程終止。屬于某個(gè)進(jìn)程的所有
22、前臺(tái)線程都終止后,公共。屬于某個(gè)進(jìn)程的所有前臺(tái)線程都終止后,公共語(yǔ)言運(yùn)行庫(kù)就會(huì)結(jié)束該進(jìn)程,而且所有屬于該進(jìn)程的后語(yǔ)言運(yùn)行庫(kù)就會(huì)結(jié)束該進(jìn)程,而且所有屬于該進(jìn)程的后臺(tái)線程也都會(huì)立即停止,而不管后臺(tái)工作是否完成。臺(tái)線程也都會(huì)立即停止,而不管后臺(tái)工作是否完成。利用利用Thread對(duì)象的對(duì)象的IsBackground屬性,可以設(shè)置或判屬性,可以設(shè)置或判斷一個(gè)線程是后臺(tái)線程還是前臺(tái)線程。斷一個(gè)線程是后臺(tái)線程還是前臺(tái)線程。通過(guò)將某個(gè)線程的通過(guò)將某個(gè)線程的IsBackground屬性設(shè)置為屬性設(shè)置為true,使,使其變?yōu)楹笈_(tái)線程。其變?yōu)楹笈_(tái)線程。默認(rèn)情況下,屬于托管線程池的線程(即其默認(rèn)情況下,屬于托管線程池
23、的線程(即其IsThreadPoolThread屬性為屬性為true的線程)都是后臺(tái)線的線程)都是后臺(tái)線程,通過(guò)創(chuàng)建并啟動(dòng)新的程,通過(guò)創(chuàng)建并啟動(dòng)新的Thread對(duì)象而生成的線程都是對(duì)象而生成的線程都是前臺(tái)線程。前臺(tái)線程。23232.3.2 線程的基本操作線程的基本操作1.啟動(dòng)線程啟動(dòng)線程啟動(dòng)無(wú)參數(shù)線程的方法啟動(dòng)無(wú)參數(shù)線程的方法啟動(dòng)線程前,首先要?jiǎng)?chuàng)建一個(gè)線程。啟動(dòng)線程前,首先要?jiǎng)?chuàng)建一個(gè)線程。u第一步:創(chuàng)建無(wú)參數(shù)線程。例如:第一步:創(chuàng)建無(wú)參數(shù)線程。例如: Thread t1 = new Thread(方法名方法名);u第二步:調(diào)用第二步:調(diào)用Start方法啟動(dòng)線程。例如:方法啟動(dòng)線程。例如: t1
24、.Start(); /不帶參數(shù)不帶參數(shù)注意:調(diào)用注意:調(diào)用Start只是告訴系統(tǒng)啟動(dòng)該線程,但只是告訴系統(tǒng)啟動(dòng)該線程,但是系統(tǒng)并不一定會(huì)立即啟動(dòng)它。是系統(tǒng)并不一定會(huì)立即啟動(dòng)它。2424啟動(dòng)線程舉例啟動(dòng)線程舉例1執(zhí)行無(wú)參數(shù)方法執(zhí)行無(wú)參數(shù)方法/定義無(wú)參數(shù)的方法定義無(wú)參數(shù)的方法static void MethodA() for (int i = 0; i 10; i+) Console.WriteLine(i的當(dāng)前值是的當(dāng)前值是: + i); /創(chuàng)建創(chuàng)建線程線程并啟動(dòng)線程并啟動(dòng)線程Thread t1 = new Thread(new ThreadStart(MethodA);t1.Start();T
25、hread t2 = new Thread(MethodA);t2.Start();2525補(bǔ)充例題補(bǔ)充例題【E07-ThreadConsoleApplication】定義方法定義方法MethodAstatic void MethodA() for (int i = 0; i 10; i+) Console.WriteLine(i的當(dāng)?shù)漠?dāng)前值是前值是: + i); 定義方法定義方法MethodBstatic void MethodB() for (int j = 0; j 10; j+) Console.WriteLine(“j的當(dāng)?shù)漠?dāng)前值是前值是: + j); 在在Main方法內(nèi)創(chuàng)建線程方法
26、內(nèi)創(chuàng)建線程并啟動(dòng)線程并啟動(dòng)線程Thread t1 = new Thread(new ThreadStart(MethodA); t1.Start();Thread t2 = new Thread(new ThreadStart(MethodB); t2.Start();2626補(bǔ)充例題補(bǔ)充例題【E07-ThreadConsoleApplication】程序運(yùn)行結(jié)果程序運(yùn)行結(jié)果27272.3.2 線程的基本操作線程的基本操作1.啟動(dòng)線程啟動(dòng)線程啟動(dòng)有參數(shù)線程的方法啟動(dòng)有參數(shù)線程的方法 要求:必須傳遞一個(gè)要求:必須傳遞一個(gè)Object類型的參數(shù)類型的參數(shù)(1)傳遞單個(gè)參數(shù))傳遞單個(gè)參數(shù)u創(chuàng)建帶參數(shù)
27、線程(必須傳遞一個(gè)創(chuàng)建帶參數(shù)線程(必須傳遞一個(gè)Object類型的參類型的參數(shù)):數(shù)): Thread t2 = new Thread(方法名方法名(Object obj);u調(diào)用調(diào)用Start方法啟動(dòng)線程,并將參數(shù)傳過(guò)去。例如:方法啟動(dòng)線程,并將參數(shù)傳過(guò)去。例如: t2.Start(“myClass”); /帶參數(shù)帶參數(shù)2828線程啟動(dòng)舉例線程啟動(dòng)舉例2傳遞單個(gè)參數(shù)傳遞單個(gè)參數(shù)源碼見(jiàn)補(bǔ)充例題源碼見(jiàn)補(bǔ)充例題【E07-ThreadConsoleApplication】/定義參數(shù)類型為定義參數(shù)類型為Object的方法的方法 static void MethodC(object obj)Console
28、.WriteLine(obj.ToString();/創(chuàng)建線程創(chuàng)建線程Thread t3 = new Thread(new ParameterizedThreadStart(MethodC);Thread t4 = new Thread(MethodC);/傳遞參數(shù)并啟動(dòng)線程傳遞參數(shù)并啟動(dòng)線程t3.Start(Thread T3);t4.Start(Thread T4);29292.3.2 線程的基本操作線程的基本操作1.啟動(dòng)線程啟動(dòng)線程傳遞多個(gè)參數(shù)傳遞多個(gè)參數(shù) 解決辦法:將參數(shù)封裝到一個(gè)類或結(jié)構(gòu)中,然后傳解決辦法:將參數(shù)封裝到一個(gè)類或結(jié)構(gòu)中,然后傳遞該類或結(jié)構(gòu)的實(shí)例。遞該類或結(jié)構(gòu)的實(shí)例。 具
29、體步驟:具體步驟: 定義封裝類或結(jié)構(gòu);定義封裝類或結(jié)構(gòu); 定義帶定義帶Object類型參數(shù)的方法;類型參數(shù)的方法; 初始化類或結(jié)構(gòu)實(shí)例;初始化類或結(jié)構(gòu)實(shí)例; 創(chuàng)建線程執(zhí)行有參方法;創(chuàng)建線程執(zhí)行有參方法; 啟動(dòng)線程傳遞參數(shù);啟動(dòng)線程傳遞參數(shù);3030線程啟動(dòng)舉例線程啟動(dòng)舉例3傳遞多個(gè)參數(shù)傳遞多個(gè)參數(shù)第一步:自定義類封裝數(shù)據(jù)第一步:自定義類封裝數(shù)據(jù)struct Data public int i; public string name; public string pwd; 第二步:定義參數(shù)類型為第二步:定義參數(shù)類型為Object類類型的方法型的方法/有參數(shù)的方法有參數(shù)的方法public void
30、 Method3(Object obj) Data data = (Data)obj;Console.WriteLine(方法方法3: + data.i + + data.pwd);第三步:實(shí)例化對(duì)象第三步:實(shí)例化對(duì)象 Data data = new Data(); data.i = 0; = lee; data.pwd = pwd;第四步:創(chuàng)建線程第四步:創(chuàng)建線程Thread myThread3 = new Thread(Method3);第五步:傳遞參數(shù)第五步:傳遞參數(shù)myThread3.Start(data);31312.3.2 線程的基本操作線程
31、的基本操作1.啟動(dòng)線程啟動(dòng)線程 考慮這種情況:需要向線程傳遞多個(gè)參數(shù),但是線考慮這種情況:需要向線程傳遞多個(gè)參數(shù),但是線程執(zhí)行的方法是無(wú)參的,該如何實(shí)現(xiàn)?程執(zhí)行的方法是無(wú)參的,該如何實(shí)現(xiàn)? 解決辦法:將多個(gè)參數(shù)和線程要執(zhí)行的方法封裝到解決辦法:將多個(gè)參數(shù)和線程要執(zhí)行的方法封裝到同一個(gè)類中,然后再初始化類的實(shí)例,創(chuàng)建線程執(zhí)同一個(gè)類中,然后再初始化類的實(shí)例,創(chuàng)建線程執(zhí)行類實(shí)例的無(wú)參實(shí)例方法,即可達(dá)到向無(wú)參數(shù)線程行類實(shí)例的無(wú)參實(shí)例方法,即可達(dá)到向無(wú)參數(shù)線程傳遞多個(gè)數(shù)據(jù)的目的。傳遞多個(gè)數(shù)據(jù)的目的。3232線程啟動(dòng)舉例線程啟動(dòng)舉例4向無(wú)參線程傳遞參數(shù)向無(wú)參線程傳遞參數(shù)1. 定義類封裝數(shù)據(jù)和方法定義類封裝
32、數(shù)據(jù)和方法class Person public string name; public string pwd; public void Method2() while (true) Thread.Sleep(1000);Debug.WriteLine(String.Format(方法方法2:參數(shù):參數(shù)0 1, name, pwd); 2. 創(chuàng)建類的實(shí)例創(chuàng)建類的實(shí)例 Person person = new Person(); person. name = myName; person. pwd = mypwd;3. 創(chuàng)建線程執(zhí)行無(wú)參的實(shí)例方創(chuàng)建線程執(zhí)行無(wú)參的實(shí)例方法法myThread2 = n
33、ew Thread(person.Method2);4. 啟動(dòng)線程啟動(dòng)線程myThread2.Start();33332.3.2 線程的基本操作線程的基本操作2.終止線程終止線程 兩種方法:兩種方法: 事先設(shè)置一個(gè)事先設(shè)置一個(gè)布爾字段布爾字段,在其他線程中通過(guò)修改該,在其他線程中通過(guò)修改該布爾量的值作為傳遞給該線程是否需要終止的判斷布爾量的值作為傳遞給該線程是否需要終止的判斷條件,而在該線程中循環(huán)判斷該布爾值,以確定是條件,而在該線程中循環(huán)判斷該布爾值,以確定是否退出線程,這是結(jié)束線程比較好的方法,實(shí)際應(yīng)否退出線程,這是結(jié)束線程比較好的方法,實(shí)際應(yīng)用中一般使用這種方法。用中一般使用這種方法。
34、調(diào)用調(diào)用Thread類的類的Abort方法方法,該方法的最終效果是,該方法的最終效果是強(qiáng)行終止線程。強(qiáng)行終止線程。34342.3.2 線程的基本操作線程的基本操作3. 暫停線程暫停線程 在多線程應(yīng)用程序中,有時(shí)候并不希望某一個(gè)線程繼續(xù)在多線程應(yīng)用程序中,有時(shí)候并不希望某一個(gè)線程繼續(xù)執(zhí)行,而是希望該線程暫停一段時(shí)間,這樣,執(zhí)行,而是希望該線程暫停一段時(shí)間,這樣,CPU就會(huì)就會(huì)將其時(shí)間片中剩余的部分讓給另一個(gè)線程。將其時(shí)間片中剩余的部分讓給另一個(gè)線程。 調(diào)用調(diào)用Thread類的類的Sleep方法可以實(shí)現(xiàn)這個(gè)功能。例如:方法可以實(shí)現(xiàn)這個(gè)功能。例如: Thread.Sleep(1000); 這條語(yǔ)句的
35、功能是讓當(dāng)前線程暫停這條語(yǔ)句的功能是讓當(dāng)前線程暫停1000毫秒。毫秒。注意注意:Sleep方法是靜態(tài)方法,暫停的是該語(yǔ)句所在的方法是靜態(tài)方法,暫停的是該語(yǔ)句所在的線程,而不是其他線程。線程,而不是其他線程。35352.3.2 線程的基本操作線程的基本操作4.合并線程合并線程 Join方法用于把指定的線程合并到當(dāng)前線程中,從而使其方法用于把指定的線程合并到當(dāng)前線程中,從而使其變?yōu)橐粋€(gè)單個(gè)的線程。變?yōu)橐粋€(gè)單個(gè)的線程。 如果一個(gè)線程如果一個(gè)線程t1在執(zhí)行的過(guò)程中需要等待另一個(gè)線程在執(zhí)行的過(guò)程中需要等待另一個(gè)線程t2結(jié)束結(jié)束后才能繼續(xù)執(zhí)行,可以在后才能繼續(xù)執(zhí)行,可以在t1的代碼塊中調(diào)用的代碼塊中調(diào)用t
36、2的的join方法。方法。例如:例如: t2.Join(); 功能:功能:t1在執(zhí)行到在執(zhí)行到t2.Join()語(yǔ)句后,就處于暫停狀態(tài),直到語(yǔ)句后,就處于暫停狀態(tài),直到t2結(jié)束后才會(huì)繼續(xù)執(zhí)行。結(jié)束后才會(huì)繼續(xù)執(zhí)行。 為了避免為了避免t1一直等待,可以在調(diào)用一直等待,可以在調(diào)用t2的的Join方法的時(shí)候指方法的時(shí)候指定一個(gè)暫停時(shí)間,例如:定一個(gè)暫停時(shí)間,例如:t2.Join(100);36362.3.3 Volatile關(guān)鍵字關(guān)鍵字 volatile修飾符表示所聲明的字段可以被多個(gè)并發(fā)執(zhí)行的線修飾符表示所聲明的字段可以被多個(gè)并發(fā)執(zhí)行的線程修改。程修改。如果某個(gè)字段聲明包含如果某個(gè)字段聲明包含vol
37、atile關(guān)鍵字,則該字段關(guān)鍵字,則該字段將不再被編譯器優(yōu)化。這樣可以確保該字段在任何時(shí)間呈現(xiàn)將不再被編譯器優(yōu)化。這樣可以確保該字段在任何時(shí)間呈現(xiàn)的都是最新的值。的都是最新的值。 對(duì)于由多個(gè)線程訪問(wèn)的字段,而且該字段沒(méi)有用對(duì)于由多個(gè)線程訪問(wèn)的字段,而且該字段沒(méi)有用lock語(yǔ)句對(duì)語(yǔ)句對(duì)訪問(wèn)進(jìn)行序列化,聲明字段時(shí)應(yīng)該使用訪問(wèn)進(jìn)行序列化,聲明字段時(shí)應(yīng)該使用volatile修飾符。修飾符。 volatile修飾符只能包含在類或結(jié)構(gòu)的字段聲明中修飾符只能包含在類或結(jié)構(gòu)的字段聲明中,不能將不能將局部變量聲明為局部變量聲明為volatile。 在布爾型字段的聲明中,添加在布爾型字段的聲明中,添加volati
38、le修飾符的方法如下:修飾符的方法如下: public volatile bool shouldStop;37372.3.3 Volatile關(guān)鍵字關(guān)鍵字volatile修飾符可應(yīng)用于以下類型修飾符可應(yīng)用于以下類型:(1)引用類型。)引用類型。(2)指針類型(在不安全的上下文中)。)指針類型(在不安全的上下文中)。(3)整型整型,如,如sbyte、byte、short、ushort、int、uint、char、float和和bool。(4)具有整數(shù)基類型的枚舉類型。)具有整數(shù)基類型的枚舉類型。(5)已知為引用類型的泛型類型參數(shù)。)已知為引用類型的泛型類型參數(shù)。(6)IntPtr和和UIntPt
39、r。3838線程用法舉例線程用法舉例4線程的基本操作線程的基本操作 線程的操作(補(bǔ)充例題線程的操作(補(bǔ)充例題E01-WhyThread)39392.3.4 在一個(gè)線程中操作另一個(gè)線程的控件在一個(gè)線程中操作另一個(gè)線程的控件 默認(rèn)情況下,在默認(rèn)情況下,在Windows應(yīng)用程序中,應(yīng)用程序中,.NET Framework不允許在一個(gè)線程中直接操作另一個(gè)線程中的控件不允許在一個(gè)線程中直接操作另一個(gè)線程中的控件,這是,這是因?yàn)樵L問(wèn)因?yàn)樵L問(wèn)Windows窗體控件本質(zhì)上不是線程安全的。窗體控件本質(zhì)上不是線程安全的。 在應(yīng)用程序中,如果創(chuàng)建某控件的線程之外的其他線程試在應(yīng)用程序中,如果創(chuàng)建某控件的線程之外的其
40、他線程試圖調(diào)用該控件,則系統(tǒng)會(huì)引發(fā)一個(gè)圖調(diào)用該控件,則系統(tǒng)會(huì)引發(fā)一個(gè)InvalidOperationException異常。異常。 有兩種辦法可以解決這個(gè)問(wèn)題:有兩種辦法可以解決這個(gè)問(wèn)題: (1)使用委托()使用委托(delegate)操作另一個(gè)線程中的控件)操作另一個(gè)線程中的控件 (2)用)用BackgroundWorker組件在后臺(tái)執(zhí)行線程組件在后臺(tái)執(zhí)行線程40402.3.4 在一個(gè)線程中操作另一個(gè)線程的控件(續(xù))在一個(gè)線程中操作另一個(gè)線程的控件(續(xù)) 利用委托調(diào)用另一個(gè)線程控件利用委托調(diào)用另一個(gè)線程控件:delegate void AppendStringDelegate(string
41、str);private void AppendString(string str) if(richTextBox1.InvokeRequired) AppendStringDelegate d = AppendString; richTextBox1.Invoke(d, str); else richTextBox1.Text += str; 4141程序舉例【例程序舉例【例2-3】【例例2-3】在在Class1類中聲明兩個(gè)方法類中聲明兩個(gè)方法Method1和和Method2,其中,其中Method1不停地輸出字符不停地輸出字符“a”,Method2不停地輸出字符不停地輸出字符“b”,在,在
42、Form1中啟動(dòng)線中啟動(dòng)線程執(zhí)行程執(zhí)行Method1和和Method2,并在,并在RichTextBox中中顯示線程輸出的字符。(顯示線程輸出的字符。(ThreadExample)42422.4 線程同步與線程池線程同步與線程池2.4.1 線程的優(yōu)先級(jí)線程的優(yōu)先級(jí)2.4.2 線程同步線程同步2.4.3 lock語(yǔ)句語(yǔ)句2.4.4 線程池線程池43432.4.1 線程的優(yōu)先級(jí)線程的優(yōu)先級(jí) 五個(gè)優(yōu)先級(jí),由高到低分別是:五個(gè)優(yōu)先級(jí),由高到低分別是:Highest、AboveNormal、Normal(默認(rèn))、(默認(rèn))、BelowNormal和和Lowest 可以使用下面的方法為其賦予較高的優(yōu)先級(jí):可
43、以使用下面的方法為其賦予較高的優(yōu)先級(jí): Thread t = new Thread(MethodName); t.priority = ThreadPriority.AboveNormal; 通過(guò)設(shè)置線程的優(yōu)先級(jí)可以改變線程的執(zhí)行順序,所設(shè)通過(guò)設(shè)置線程的優(yōu)先級(jí)可以改變線程的執(zhí)行順序,所設(shè)置的優(yōu)先級(jí)僅僅適用于這些線程所屬的進(jìn)程。置的優(yōu)先級(jí)僅僅適用于這些線程所屬的進(jìn)程。 注意:注意: 當(dāng)把某線程的優(yōu)先級(jí)設(shè)置為當(dāng)把某線程的優(yōu)先級(jí)設(shè)置為Highest時(shí),系統(tǒng)正在運(yùn)行的時(shí),系統(tǒng)正在運(yùn)行的其他線程都會(huì)終止,所以使用這個(gè)優(yōu)先級(jí)別時(shí)要特別小其他線程都會(huì)終止,所以使用這個(gè)優(yōu)先級(jí)別時(shí)要特別小心。心。44442.4
44、.2 線程同步線程同步同步同步 指多個(gè)線程之間存在先后執(zhí)行順序的關(guān)聯(lián)關(guān)系指多個(gè)線程之間存在先后執(zhí)行順序的關(guān)聯(lián)關(guān)系。哪些資源需要同步哪些資源需要同步u系統(tǒng)資源(如通信端口)系統(tǒng)資源(如通信端口)u多個(gè)進(jìn)程所共享的資源(如文件句柄)多個(gè)進(jìn)程所共享的資源(如文件句柄)u由多個(gè)線程訪問(wèn)的單個(gè)應(yīng)用程序域的資源(如全由多個(gè)線程訪問(wèn)的單個(gè)應(yīng)用程序域的資源(如全局、靜態(tài)和實(shí)例字段)局、靜態(tài)和實(shí)例字段)45452.4.2 線程同步線程同步為什么要同步為什么要同步 當(dāng)兩個(gè)線程當(dāng)兩個(gè)線程t1和和t2有相同的優(yōu)先級(jí),并且同時(shí)在系有相同的優(yōu)先級(jí),并且同時(shí)在系統(tǒng)上運(yùn)行時(shí),如果先把時(shí)間片分給統(tǒng)上運(yùn)行時(shí),如果先把時(shí)間片分給t
45、1使用,它在結(jié)構(gòu)使用,它在結(jié)構(gòu)s1中(該結(jié)構(gòu)中有多個(gè)變量)寫入某些值,但如果中(該結(jié)構(gòu)中有多個(gè)變量)寫入某些值,但如果在時(shí)間片用完時(shí)它仍沒(méi)有完成寫入,這時(shí)由于時(shí)間片在時(shí)間片用完時(shí)它仍沒(méi)有完成寫入,這時(shí)由于時(shí)間片已經(jīng)分給已經(jīng)分給t2使用,而使用,而t2又恰好要嘗試讀取該結(jié)構(gòu)的值,又恰好要嘗試讀取該結(jié)構(gòu)的值,此時(shí)讀出的就不是正確的值。這種情況下,如果使用此時(shí)讀出的就不是正確的值。這種情況下,如果使用同步僅允許一個(gè)線程使用同步僅允許一個(gè)線程使用s1,在該線程完成對(duì),在該線程完成對(duì)s1的的寫入工作后再讓寫入工作后再讓t2讀取這個(gè)結(jié)構(gòu)值,就可以避免出現(xiàn)讀取這個(gè)結(jié)構(gòu)值,就可以避免出現(xiàn)此類錯(cuò)誤。此類錯(cuò)誤。4
46、6462.4.2 線程同步線程同步解決方法解決方法:uSystem.Threading命名空間提供了多個(gè)用于同步命名空間提供了多個(gè)用于同步線程的類這些類包括線程的類這些類包括Mutex、Monitor、Interlocked和和AutoResetEvent。其中:。其中:uMutex類鎖定多線程間同步調(diào)用,即鎖定調(diào)用端。類鎖定多線程間同步調(diào)用,即鎖定調(diào)用端。uMonitor、Lock語(yǔ)句鎖定數(shù)據(jù)或者被調(diào)用的函數(shù),語(yǔ)句鎖定數(shù)據(jù)或者被調(diào)用的函數(shù),即鎖定被調(diào)用端。即鎖定被調(diào)用端。u在實(shí)際應(yīng)用中在實(shí)際應(yīng)用中經(jīng)常使用經(jīng)常使用lock語(yǔ)句語(yǔ)句完成線程同步。完成線程同步。該語(yǔ)句簡(jiǎn)化了編程的復(fù)雜性,使程序看起
47、來(lái)既清晰該語(yǔ)句簡(jiǎn)化了編程的復(fù)雜性,使程序看起來(lái)既清晰又簡(jiǎn)潔又簡(jiǎn)潔47472.4.3 lock語(yǔ)句語(yǔ)句lock語(yǔ)句的功能語(yǔ)句的功能u lock語(yǔ)句可以有效地實(shí)現(xiàn)同步,即將代碼段語(yǔ)句可以有效地實(shí)現(xiàn)同步,即將代碼段(語(yǔ)句塊)標(biāo)記為臨界區(qū)。(語(yǔ)句塊)標(biāo)記為臨界區(qū)。u lock語(yǔ)句能確保當(dāng)一個(gè)線程位于代碼的語(yǔ)句能確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)臨界區(qū)(可以理解為對(duì)某些資源進(jìn)行操作的一段代碼)(可以理解為對(duì)某些資源進(jìn)行操作的一段代碼)時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。如果其他線程試時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。如果其他線程試圖進(jìn)入鎖定的代碼段,則它將一直等待(即被阻圖進(jìn)入鎖定的代碼段,則它將一直等待(即被阻塞),直
48、到鎖定的對(duì)象被釋放以后才能進(jìn)入臨界塞),直到鎖定的對(duì)象被釋放以后才能進(jìn)入臨界區(qū)。區(qū)。48482.4.3 lock語(yǔ)句(續(xù))語(yǔ)句(續(xù))lock語(yǔ)句的用法語(yǔ)句的用法 首先利用首先利用lock語(yǔ)句鎖定某一個(gè)對(duì)象,然后執(zhí)行代碼語(yǔ)句鎖定某一個(gè)對(duì)象,然后執(zhí)行代碼段中的語(yǔ)句,等代碼段中的語(yǔ)句執(zhí)行完畢后,再釋段中的語(yǔ)句,等代碼段中的語(yǔ)句執(zhí)行完畢后,再釋放該對(duì)象。放該對(duì)象。 例如:例如:private Object obj = new Object();lock(obj) /臨界區(qū)中的代碼臨界區(qū)中的代碼49492.4.3 lock語(yǔ)句(續(xù))語(yǔ)句(續(xù))使用使用lock語(yǔ)句應(yīng)注意的問(wèn)題語(yǔ)句應(yīng)注意的問(wèn)題:u鎖定的對(duì)象
49、名(上面代碼中的鎖定的對(duì)象名(上面代碼中的obj)一般聲)一般聲明為明為Object類型,不要將其聲明為值類型。類型,不要將其聲明為值類型。u鎖定的對(duì)象名不能將其聲明為鎖定的對(duì)象名不能將其聲明為public,只,只能為能為privateu臨界區(qū)中的代碼一般不宜太多。臨界區(qū)中的代碼一般不宜太多。5050程序舉例【例程序舉例【例2-4】【例例2-4】lock語(yǔ)句用法舉例:多線程隨機(jī)取款。語(yǔ)句用法舉例:多線程隨機(jī)取款。 (相當(dāng)于某公司派多人在多臺(tái)自動(dòng)取款機(jī)上同時(shí)取款)(相當(dāng)于某公司派多人在多臺(tái)自動(dòng)取款機(jī)上同時(shí)取款)運(yùn)行效果:(運(yùn)行效果:(lockExample)正確的運(yùn)行結(jié)果正確的運(yùn)行結(jié)果 錯(cuò)誤的運(yùn)
50、行結(jié)果錯(cuò)誤的運(yùn)行結(jié)果51512.4.4 線程池線程池背景:背景: 1)無(wú)限制的創(chuàng)建線程消耗系統(tǒng)資源)無(wú)限制的創(chuàng)建線程消耗系統(tǒng)資源 2)創(chuàng)建線程、回收線程均需要時(shí)間)創(chuàng)建線程、回收線程均需要時(shí)間線程池的默認(rèn)大?。好總€(gè)可用處理器線程池的默認(rèn)大?。好總€(gè)可用處理器25個(gè)線程。個(gè)線程。 每個(gè)進(jìn)程都有一個(gè)線程池。每個(gè)進(jìn)程都有一個(gè)線程池。為什么要用線程池?為什么要用線程池?u 降低系統(tǒng)開(kāi)銷降低系統(tǒng)開(kāi)銷u 可以重用資源,使應(yīng)用程序可以避免為每個(gè)任務(wù)可以重用資源,使應(yīng)用程序可以避免為每個(gè)任務(wù)創(chuàng)建新線程引起的資源和時(shí)間消耗。創(chuàng)建新線程引起的資源和時(shí)間消耗。52522.4.4 線程池(續(xù))線程池(續(xù))線程池:線程池
51、:是在是在后臺(tái)執(zhí)行后臺(tái)執(zhí)行多個(gè)任務(wù)的線程集合。多個(gè)任務(wù)的線程集合。 1)最大線程數(shù)最大線程數(shù)限制。如果所有線程都繁忙,則額外限制。如果所有線程都繁忙,則額外的任務(wù)將放入等待隊(duì)列中,直到有線程可用時(shí)才能夠的任務(wù)將放入等待隊(duì)列中,直到有線程可用時(shí)才能夠得到處理。得到處理。 2)最小線程數(shù)最小線程數(shù)=創(chuàng)建線程池時(shí)應(yīng)立即啟動(dòng)的數(shù)目創(chuàng)建線程池時(shí)應(yīng)立即啟動(dòng)的數(shù)目 3)一旦池中的某個(gè)線程完成任務(wù),它將返回到等待)一旦池中的某個(gè)線程完成任務(wù),它將返回到等待線程隊(duì)列中,等待被再次使用。這種重用使應(yīng)用程序線程隊(duì)列中,等待被再次使用。這種重用使應(yīng)用程序可以避免為每個(gè)任務(wù)創(chuàng)建新線程引起的資源和時(shí)間消可以避免為每個(gè)任務(wù)
52、創(chuàng)建新線程引起的資源和時(shí)間消耗。耗。 4)一項(xiàng)工作任務(wù)被加入到線程池的隊(duì)列中,就不能)一項(xiàng)工作任務(wù)被加入到線程池的隊(duì)列中,就不能取消該任務(wù),直到該任務(wù)完成。取消該任務(wù),直到該任務(wù)完成。53532.4.4 線程池(續(xù))線程池(續(xù))什么情況下才使用線程池?什么情況下才使用線程池?u后臺(tái)執(zhí)行,后臺(tái)執(zhí)行,而且不同線程沒(méi)有優(yōu)先級(jí)區(qū)別而且不同線程沒(méi)有優(yōu)先級(jí)區(qū)別u適用于需要多個(gè)線程而實(shí)際執(zhí)行時(shí)間又不多的場(chǎng)適用于需要多個(gè)線程而實(shí)際執(zhí)行時(shí)間又不多的場(chǎng)合合u沒(méi)有導(dǎo)致線程長(zhǎng)時(shí)間被阻塞的任務(wù)沒(méi)有導(dǎo)致線程長(zhǎng)時(shí)間被阻塞的任務(wù)(對(duì)于可能長(zhǎng)對(duì)于可能長(zhǎng)時(shí)間被阻塞的任務(wù),應(yīng)該創(chuàng)建單獨(dú)的線程處理,時(shí)間被阻塞的任務(wù),應(yīng)該創(chuàng)建單獨(dú)的線
53、程處理,不應(yīng)該使用線程池),這是因?yàn)榫€程池具有最大不應(yīng)該使用線程池),這是因?yàn)榫€程池具有最大線程數(shù)限制,大量阻塞的線程池線程可能會(huì)阻止線程數(shù)限制,大量阻塞的線程池線程可能會(huì)阻止任務(wù)啟動(dòng)任務(wù)啟動(dòng) 54542.4.4 線程池(續(xù))線程池(續(xù))ThreadPool類類位于位于System.Threading命名空間下。命名空間下。ThreadPool提供了對(duì)線程池的操作(靜態(tài)方法),提供了對(duì)線程池的操作(靜態(tài)方法),例如:發(fā)送工作項(xiàng)、處理異步例如:發(fā)送工作項(xiàng)、處理異步I/O、設(shè)置線程數(shù)目等、設(shè)置線程數(shù)目等ThreadPool是一個(gè)是一個(gè)靜態(tài)類靜態(tài)類托管線程池中的線程為后臺(tái)線程,即它們的托管線程池中的
54、線程為后臺(tái)線程,即它們的IsBackground屬性為屬性為true。這意味著在所有的前臺(tái)。這意味著在所有的前臺(tái)線程都已退出后,線程都已退出后,ThreadPool線程也會(huì)自動(dòng)退出線程也會(huì)自動(dòng)退出55552.4.4 線程池(續(xù))線程池(續(xù)) GetAvailableThreads方法:檢索由方法:檢索由GetMaxThreads返回的返回的線程池線程的最大數(shù)目和當(dāng)前活動(dòng)數(shù)目之間的差值線程池線程的最大數(shù)目和當(dāng)前活動(dòng)數(shù)目之間的差值 GetMaxThreads方法:檢索可以同時(shí)處于活動(dòng)狀態(tài)的線程池方法:檢索可以同時(shí)處于活動(dòng)狀態(tài)的線程池請(qǐng)求的數(shù)目。所有大于此數(shù)目的請(qǐng)求將保持排隊(duì)狀態(tài),直到請(qǐng)求的數(shù)目。所
55、有大于此數(shù)目的請(qǐng)求將保持排隊(duì)狀態(tài),直到線程池線程變?yōu)榭捎镁€程池線程變?yōu)榭捎?GetMinThreads方法:檢索線程池在新請(qǐng)求預(yù)測(cè)中維護(hù)的空方法:檢索線程池在新請(qǐng)求預(yù)測(cè)中維護(hù)的空閑線程數(shù)閑線程數(shù) SetMaxThreads方法:可以同時(shí)處于活動(dòng)狀態(tài)的線程池的請(qǐng)方法:可以同時(shí)處于活動(dòng)狀態(tài)的線程池的請(qǐng)求數(shù)目。所有大于此數(shù)目的請(qǐng)求將保持排隊(duì)狀態(tài),直到線程求數(shù)目。所有大于此數(shù)目的請(qǐng)求將保持排隊(duì)狀態(tài),直到線程池線程變?yōu)榭捎谩3鼐€程變?yōu)榭捎谩?SetMinThreads方法方法:設(shè)置線程池在新請(qǐng)求預(yù)測(cè)中維護(hù)的空設(shè)置線程池在新請(qǐng)求預(yù)測(cè)中維護(hù)的空閑線程數(shù)閑線程數(shù)56562.4.4 線程池(續(xù))線程池(續(xù)) Q
56、ueueUserWorkItem方法功能:方法功能:u功能:請(qǐng)求線程池處理一個(gè)任務(wù)或者工作項(xiàng)功能:請(qǐng)求線程池處理一個(gè)任務(wù)或者工作項(xiàng)u運(yùn)行時(shí)線程池會(huì)自動(dòng)為每一個(gè)任務(wù)創(chuàng)建線程并且在任運(yùn)行時(shí)線程池會(huì)自動(dòng)為每一個(gè)任務(wù)創(chuàng)建線程并且在任務(wù)結(jié)束時(shí)釋放線程。務(wù)結(jié)束時(shí)釋放線程。u語(yǔ)法語(yǔ)法:帶一個(gè)帶一個(gè)WaitCallback委托的參數(shù),這個(gè)參數(shù)包裝委托的參數(shù),這個(gè)參數(shù)包裝了要完成的任務(wù)了要完成的任務(wù) Public static bool QueueUserWorkItem ( WaitCallback callBack, object state) Public static bool QueueUserWorkItem ( WaitCallback callBack)參數(shù)參數(shù):state:包含方法所用數(shù)據(jù)的對(duì)象包含方法所用數(shù)據(jù)的對(duì)象callBack: System.Threading.WaitCallback,它表示要,它表示要執(zhí)行的方法執(zhí)行的方法57572.4.4 線程池
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度網(wǎng)絡(luò)安全項(xiàng)目建議書(shū)委托合同3篇
- 專利權(quán)與著作權(quán)全面轉(zhuǎn)讓合同范本2024年版版B版
- 2025年度城市綠化工程苗木購(gòu)銷及養(yǎng)護(hù)管理合同4篇
- 2025年度數(shù)據(jù)中心設(shè)備租賃合同4篇
- 二零二五年度玻璃幕墻玻璃深加工定制合同范本3篇
- 2024年可穿戴設(shè)備研發(fā)生產(chǎn)合同
- 工業(yè)節(jié)能改造項(xiàng)目合同能源管理協(xié)議
- 建設(shè)監(jiān)理合同補(bǔ)充協(xié)議
- 廣告投放渠道優(yōu)化合作合同
- 智能硬件制造基地投資合同
- 高處作業(yè)安全培訓(xùn)課件-
- 職中英語(yǔ)期末考試質(zhì)量分析
- 中國(guó)的世界遺產(chǎn)智慧樹(shù)知到答案章節(jié)測(cè)試2023年遼寧科技大學(xué)
- 急性腹瀉與慢性腹瀉修改版
- 先天性肌性斜頸的康復(fù)
- 《國(guó)際市場(chǎng)營(yíng)銷》案例
- GB/T 37518-2019代理報(bào)關(guān)服務(wù)規(guī)范
- GB/T 156-2017標(biāo)準(zhǔn)電壓
- PPT溝通的藝術(shù)課件
- 內(nèi)科學(xué):巨幼細(xì)胞性貧血課件
- 暑假家校聯(lián)系情況記錄表
評(píng)論
0/150
提交評(píng)論