溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

.Net組件程序設(shè)計(jì)之線程、并發(fā)管理(一)

發(fā)布時間:2020-06-26 22:27:35 來源:網(wǎng)絡(luò) 閱讀:712 作者:jinyuan0829 欄目:編程語言

.Net組件程序設(shè)計(jì)之線程、并發(fā)管理(一)

1.線程

  • 線程

  • 線程的創(chuàng)建

  • 線程的阻塞

    • 線程掛起

    • 線程睡眠

    • 加入線程

    • 線程中止

現(xiàn)在幾乎所有的應(yīng)用程序都是多線程的,給用戶看來就是一個應(yīng)用程序界面(應(yīng)用程序線程),不管什么操作都不會導(dǎo)致界面出現(xiàn)響應(yīng)慢的情況,這些都是多線程的功勞,有了多線程,可以讓應(yīng)用程序盡最大可能的處理更多的操作,調(diào)動很多線程來并行處理請求,這樣會使得應(yīng)用程序有更大的系統(tǒng)吞吐量。

1.線程

1.1線程

線程是什么呢?線程就是進(jìn)程中的一條執(zhí)行路徑,每個應(yīng)用程序至少在一個線程上運(yùn)行。在本篇中將會對線程稍作講解.

在.NET中,線程是執(zhí)行的基本單元。在.NET中的線程并非是操作系統(tǒng)中的物理線程,而是對物理線程的托管代碼表示。

在.NET System.Threading命名空間下,有個Thread類型的類,它就是代表著托管線程。

1.2線程的創(chuàng)建

 我們直接來看下線程創(chuàng)建的示例:

1     public class ThreadingMethodCase
2     {
3         public static void ThreadingMethod()
4         {
5             Thread thread = Thread.CurrentThread;
6             int threadid = thread.ManagedThreadId;
7             Console.WriteLine(thread.Name + "ThreadID is " + threadid);
8         }
9     }
1 ThreadStart threadstart = new ThreadStart(ThreadingMethodCase.ThreadingMethod);
2 Thread thread = new Thread(threadstart);
3 thread.Name = "SubThread";
4 thread.Start();

在.NET中創(chuàng)建一個線程首先需要線程方法,什么叫線程方法?首先線程是一個操作或是一組操作的表示,線程方法就是前面這句話中的【操作】。
這里先看一下Thread類型的構(gòu)造函數(shù)接受了一個ThreadStart類型的無參數(shù)委托,這個是好理解的。
線程創(chuàng)建了必須要顯示的調(diào)用它的Start()函數(shù)才能開始執(zhí)行線程。調(diào)用Strat()函數(shù)是不會對當(dāng)前線程造成阻塞的,就是說在調(diào)用了之后控制權(quán)會立刻的回到當(dāng)前的線程的客戶端中。

1.3線程的阻塞

1.3.1線程掛起
1 public sealed class Thread
2 {
3    public void Suspend();
4    public void Resume();
5    ……
6 }

Suspend()方法是掛起線程的執(zhí)行.

Resume()方法則是釋放掛起的線程,讓線程繼續(xù)執(zhí)行在調(diào)用Suspend()方法的時候,是不會造成當(dāng)前線程阻塞的,在調(diào)用后,控制權(quán)立即返回的,而且在要被掛起的線程中, 也不是被立即掛起的,而是在執(zhí)行到一個安全點(diǎn)的時候,才會執(zhí)行掛機(jī)操作的。什么是安全點(diǎn)?舉個例子吧,假如要被掛起的線程中 正在執(zhí)行一個函數(shù)的時候,外部被通知命令,要被掛起,這個時候線程是不會被掛起的,當(dāng)這個函數(shù)執(zhí)行完畢的時候,線程則會被掛起, 假設(shè)編輯器是把安全點(diǎn)插設(shè)在每個函數(shù)的末端的。

.NET中是不推薦我們使用這兩個函數(shù)的,因?yàn)闀斐珊芏喾矫娴牟环€(wěn)定。

1.3.2線程睡眠

 

1 public sealed class Thread
2 {
3    public static void Sleep(int millisecondsTimeout);
4    public static void Sleep(TimeSpan timeout);
5    ……
6 }

Sleep()是靜態(tài)函數(shù),是一個阻塞調(diào)用并且使當(dāng)前線程放棄CPU時間片,就是在休眠指定的時間后,控制權(quán)才會返回到調(diào)用的線程。

Thread.Sleep(20);//讓當(dāng)前調(diào)用線程休眠20毫秒

Thread類還提供了另一種類似于休眠的操作:

1 public static void SpinWait(int iterations);

調(diào)用SpinWait()也是會造成當(dāng)前阻塞的,但是當(dāng)前線程不會放棄CPU時間片,而是在等待有限的時間(參數(shù)設(shè)置)后繼續(xù)執(zhí)行, 這種函數(shù)是在可控的情況下才去這樣調(diào)用的,比如說當(dāng)前線程要使用一個資源,而這個資源在被其他線程使用,那么就可以使用 SpinWait()函數(shù),在等待有限的時間后,再去讀取資源,如果資源還沒被其他線程釋放,當(dāng)前線程也會繼續(xù)執(zhí)行,所有這是用于可控的情況下的方法。

1.3.3 加入線程

Thread類的Join()方法可以讓一個線程等待另一個線程的終結(jié)。

這句定義什么意思呢?說是說不清的,來看一下Thread.Join()示例代碼  :

 1     public class StudyCase
 2     {
 3         public void ThreadingTest()
 4         {
 5             ThreadStart threadstart = new ThreadStart(ThreadingMethodCase.ThreadingMethod);
 6             Thread thread = new Thread(threadstart);
 7             thread.Name = "newThread";
 8             Thread.CurrentThread.Name = "CurrentThread";
 9             for (int i = 0; i < 5; i++)
10             {
11                 if (i == 0)
12                 {
13                     thread.Start();
14                     thread.Join();
15                 }
16                 Console.WriteLine(Thread.CurrentThread.Name+"_"+i.ToString());
17             }
18         }
19 
20     }

 

1     public class ThreadingMethodCase
2     {
3         public static void ThreadingMethod()
4         {
5             Thread thread = Thread.CurrentThread;
6             int threadid = thread.ManagedThreadId;
7             Console.WriteLine(thread.Name + "ThreadID is " + threadid);
8         }
9     }

.Net組件程序設(shè)計(jì)之線程、并發(fā)管理(一)

從上圖的結(jié)果再結(jié)合代碼看一下,就大概的清楚了Join的意思了,意義就是阻塞當(dāng)前線程,等待子線程(ThreadingTest函數(shù)中的thread變量)執(zhí)行完畢時,當(dāng)前線程再執(zhí)行。

1.3.4線程中止

調(diào)用Thread類型提供的Abort()方法可以中止線程的運(yùn)行,并且被中止的線程會拋出一個ThreadAbortException類型的異常。下面的示例代碼會清晰的描述和示例代碼結(jié)果圖。
來看示例代碼:

 1     public class ThreadingMethodCase
 2     {
 3         public static void ThreadingMethodDiv()
 4         {
 5             try
 6             {
 7                 while (true)
 8                 {
 9                     Console.WriteLine("測試子線程中止");
10                 }
11             }
12             catch (ThreadAbortException abex)
13             {
14                 Console.WriteLine(Thread.CurrentThread.Name+"-子線程內(nèi)部-" + abex.Message);
15             }
16         }
17     }
18     public class StudyCase
19     {
20         public void ThreadingTestAbort()
21         {
22             Thread.CurrentThread.Name="CurrentThread";
23             ThreadStart threadstart = new ThreadStart(ThreadingMethodCase.ThreadingMethod);
24             Thread thread = new Thread(threadstart);
25             thread.Name = "newThread";
26 
27             thread.Start();
28             for (int i = 0; i < 10; i++)
29             {
30                 Console.WriteLine(i.ToString());
31             }
32             thread.Abort();
33             thread.Join();
34 
35             Console.WriteLine("當(dāng)前線程");
36         }
37 
38     }

.Net組件程序設(shè)計(jì)之線程、并發(fā)管理(一)

將在下一章講解線程同步。

 

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI