国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[.net 面向對象程序設計進階] (16) 多線程(Multithreading)(一) 利用多線程提高程序性能(上)

2019-11-17 02:12:33
字體:
來源:轉載
供稿:網友

[.net 面向對象程序設計進階] (16) 多線程(Multithreading)(一) 利用多線程提高程序性能(上)

[.net 面向對象程序設計進階] (16) 多線程(Multithreading)(一)利用多線程提高程序性能(上)

本節導讀:

隨著硬件和網絡的高速發展,為多線程(Multithreading)處理并行任務,提供了有利條件。

其實我們每時每刻都在享受多線程帶來的便利,多核處理器多線程工作、Windows操作系統、Web服務器都在使用多線程工作。

使用多線程直接提高了程序的執行效率,因此學習多線程對提高程序運行能力非常必要,本節主要介紹多線程原理及.NET中多線程在.NET面向對象程序設計中的應用。

讀前必備:

本節需要了解Lambda表達式基礎及匿名方法和匿名委托相關知識;

A.委托 [.net面向對象編程基礎](20)委托

B.Lamda表達式 [.net 面向對象程序設計進階] (5) Lamda表達式(一) 創建委托

1.關于多線程

在介紹多線程之前,先了解一下進程。

進程:獨立運行的程序稱為進程。(比如Windows系統后臺程序,也可以稱為后臺進程)

線程:對于同一個程序分為多個執行流,稱為線程。

多線程:使用多個線程進行多任務處理,稱為多線程。

2.如何合理使用多線程?

A.對于用戶等待程序處理時,可以使用多線程處理耗時任務;

B.對于一些不需要即時完成的任務,可以使用后臺任務線程處理;

C.對于多并發任務,可以使用多線程同時處理;

D.對于通訊類,比如對線程阻塞,可以使用多線程。

除過上面的幾個常用的情況,還有很多情況下可以使用多線程。

3.多線程的缺點線程自然也有缺點,以下列出了一些:A.如果有大量的線程,會影響性能,因為操作系統需要在他們之間切換;B.更多的線程需要更多的內存空間;C.線程會給程序帶來更多的bug,因此要小心使用,比如:線程任務在執行完成后,要及時釋放內存;D.線程的中止需要考慮其對程序運行的影響。

4..NET中的兩種多線程

.NET本身就是一個多線程的的環境。

在.NET中有兩種多線程的:

一種是使用Thread類進行線程的創建、啟動,終止等操作。

一種是使用ThreadPool類用于管理線程池.

5 .NET中使用Thread進行多線程處理

5.1Thread類常用方法

.NET基礎類庫的System.Threading命名空間提供了大量的類和接口支持多線程。System.Threading.Thread類是創建并控制線程,設置其優先級并獲取其狀態最為常用的類。

下面是該類幾個至關重要的方法:Thread.Start():啟動線程的執行;Thread.Suspend():掛起線程,或者如果線程已掛起,則不起作用;Thread.Resume():繼續已掛起的線程;Thread.Interrupt():中止處于Wait或者Sleep或者Join線程狀態的線程;Thread.Join():阻塞調用線程,直到某個線程終止時為止Thread.Sleep():將當前線程阻塞指定的毫秒數;Thread.Abort():以開始終止此線程的過程。如果線程已經在終止,則不能通過Thread.Start()來啟動線程。

下面是一個簡單的線程示例:

先創建一個方法:

//簡單線程方法static void MyThreadStart(){    Console.WriteLine("我是一個簡單線程");}

創建線程調用方法:

//簡單的線程Thread myThread = new Thread(MyThreadStart);myThread.Start();

運行結果如下:

5.2Thread類常用屬性

Thread的屬性有很多,我們先看最常用的幾個:

CurrentThread:用于獲取當前線程;

ThreadState當前線程的狀態(5.4介紹);

Name:獲取或設置線程名稱;

PRiority:獲取或設置線程的優先級(5.5介紹)

ManagedThreadId:獲取當前線程的唯一標識

IsBackground:獲取或設置線程是前臺線程還是后臺線程(5.6介紹)

IsThreadPoolThread:獲取當前線程是否是托管線程池(后面章節會介紹)

下面創建一個線程示例,來說明這幾個屬性:

Thread myThreadTest = new Thread(() =>{    Thread.Sleep(1000);    Thread t = Thread.CurrentThread;    Console.WriteLine("Name: " + t.Name);    Console.WriteLine("ManagedThreadId: " + t.ManagedThreadId);    Console.WriteLine("State: " + t.ThreadState);    Console.WriteLine("Priority: " + t.Priority);    Console.WriteLine("IsBackground: " + t.IsBackground);    Console.WriteLine("IsThreadPoolThread: " + t.IsThreadPoolThread);}){    Name = "線程測試",    Priority = ThreadPriority.Highest};myThreadTest.Start();Console.WriteLine("關聯進程的運行的線程數量:"+System.Diagnostics.Process.GetCurrentProcess().Threads.Count);

運行結果如下:

5.3 帶參數的線程方法

首先我們使用Lambda表達式來改寫前面“簡單線程”中無參數的方法,如下:

//線程一new Thread(()=>{    for (int i = 0; i < 5; i++)        Console.WriteLine("我的線程一-[{0}]", i);}).Start();

運行結果如下:

上面示例創建的線程并沒有帶參數,如果是一個有參數的方法,線程該如何創建?

別擔心,.NET為我們提供了一個ParameterizedThreadStart委托來解決帶一個參數的問題,如下:

//線程二new Thread((num) =>{    for (int i = 0; i < (int)num; i++)        Console.WriteLine("我的線程二--[{0}]", i);}).Start(5);

運行結果如下:

那么問題來了,ParameterizedThreadStart委托只有一個包含數據的參數,對于多個參數呢?我們可以使用一個無參數的方法來包裝它,如下:

先創建一個帶參數的方法:

static void myThreadStart(int numA, int numB){    for (int i = (int)numA; i < (int)numB; i++)        Console.WriteLine("我的線程三---[{0}]", i);}

然后通過無參數的委托來包裝它,如下:

//線程三new Thread(() =>myThreadStart(0,5)).Start();

運行結果如下:

5.4 Thread狀態

我們對于線程啟動以后,如何進行掛起和終止、重新啟用,首先線程在運行后有一個狀態。

System.Threading.Thread.ThreadState屬性定義了執行時線程的狀態。線程從創建到線程終止,它一定處于其中某一個狀態。

A.Unstarted:當線程被創建時,它處在Unstarted狀態。

B.Running:Thread類的Start()方法將使線程狀態變為Running狀態,線程將一直處于這樣的狀態,除非我們調用了相應的方法使其掛起、阻塞、銷毀或者自然終止。

C.Suspended:如果線程被掛起,它將處于Suspended狀態。

D.Running:我們調用resume()方法使其重新執行,這時候線程將重新變為Running狀態。一

E.Stopped:旦線程被銷毀或者終止,線程處于Stopped狀態。處于這個狀態的線程將不復存在,正如線程開始啟動,線程將不可能回到Unstarted狀態。

F.Background:線程還有一個Background狀態,它表明線程運行在前臺還是后臺。在一個確定的時間,線程可能處于多個狀態。

G.WaitSleepJoin、AbortRequested:舉例子來說,一個線程被調用了Sleep而處于阻塞,而接著另外一個線程調用Abort方法于這個阻塞的線程,這時候線程將同時處于WaitSleepJoin和AbortRequested狀態。

H.一旦線程響應轉為Sle阻塞或者中止,當銷毀時會拋出ThreadAbortException異常。

ThreadState枚舉的10種執行狀態如下:

對于線程阻塞和同步問題,將在下一節繼續介紹。

5.5. 線程優先級

對于多線程任務,我們可以根據其重要性和運行所需要的資源情況,設置他的優先級System.Threading.ThreadPriority枚舉了線程的優先級別,從而決定了線程能夠得到多少CPU時間。

高優先級的線程通常會比一般優先級的線程得到更多的CPU時間,如果不止一個高優先級的線程,操作系統將在這些線程之間循環分配CPU時間。

低優先級的線程得到的CPU時間相對較少,當這里沒有高優先級的線程,操作系統將挑選下一個低優先級的線程執行。

一旦低優先級的線程在執行時遇到了高優先級的線程,它將讓出CPU給高優先級的線程。

新創建的線程優先級為一般優先級,我們可以設置線程的優先級別的值,如下面所示:

對于線程的優先級我們下面做一個實驗,開啟兩個線程(一個設置高優先級,另一個設置低優先級)。

分別委托兩個方法進行累加,看一下最終結果,代碼如下:

int numberA = 0, numberB = 0;bool state = true;new Thread(() => { while (state)numberA++; }) { Priority = ThreadPriority.Highest, Name="線程A" }.Start();new Thread(() => { while (state)numberB++; }) { Priority = ThreadPriority.Lowest , Name="線程B" }.Start();//讓主線程掛件1秒Thread.Sleep(1000);state = false;Console.WriteLine("線程A: {0}, 線程B: {1}", numberA, numberB);

運行結果如下:

.NET根據優先級分配了資源,可以看到優先級較高的線程執行的機會較大,但優先級小的線程仍然有較多的機會執行。

5.6 前臺線程和后臺線程

線程有兩種,默認情況下為前臺線程,要想設置為后臺線程也非常容易,只需要加一個屬性:thread.IsBackground=true;就可以變為一個后臺線程了。

重點來了,前后臺線程的區別:

A.前臺線程:應用程序必須執行完所有的前臺線程才能退出;

B.后臺線程:應用程序不必考慮其是否全部完成,可以直接退出。應用程序退出時,自動終止后臺線程。

下面我們使用一個輸出從0到1000的數字,來實驗一下前臺線程和后臺線程的區別:

Thread myThread = new Thread(() =>{for (int i = 0; i < 1000; i++)Console.WriteLine(i);});         var key = Console.ReadLine();if (key == "1"){    myThread.IsBackground = true;    myThread.Start();}else{    myThread.IsBackground = false;    myThread.Start();}

當我們在控制臺等級輸入的時候,

如果輸入1(后臺線程),線程會很快關閉,并不會等輸出完1000個數字再關閉;

如果輸入其它,回車后,則線程會等1000個數字輸出完后,窗口關閉;

6. 本節要點:

A.本節主要介紹了線程的基本知識;

B.Thread常用的屬性、方法;

C.Thread委托的方法有多個參數的用法;

D.Thread的優先級;

E.Thread的執行狀態;

F.前臺線程和后臺線程;

后面會繼續深入介紹利用線程提高程序性能。

==============================================================================================

返回目錄

<如果對你有幫助,記得點一下推薦哦,如有有不明白或錯誤之處,請多交流>

<對本系列文章閱讀有困難的朋友,請先看《.net 面向對象編程基礎》>

<轉載聲明:技術需要共享精神,歡迎轉載本博客中的文章,但請注明版權及URL>


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 始兴县| 珠海市| 麦盖提县| 任丘市| 娱乐| 木兰县| 缙云县| 新化县| 德令哈市| 介休市| 方正县| 黄大仙区| 调兵山市| 陇西县| 通江县| 天台县| 辛集市| 安康市| 永丰县| 岫岩| 鄱阳县| 兴义市| 贡觉县| 深泽县| 建阳市| 瑞金市| 威远县| 图木舒克市| 额济纳旗| 灵石县| 萍乡市| 龙南县| 溧水县| 洱源县| 南溪县| 兰西县| 临清市| 永福县| 萨嘎县| 秀山| 绥阳县|