.Net組件程序設計之線程、並發管理(一)
現在幾乎所有的應用程序都是多線程的,給用戶看來就是一個應用程序界面(應用程序線程),不管什麼操作都不會導致界面出現響應慢的情況,這些都是多線程的功勞,有了多線程,可以讓應用程序盡最大可能的處理更多的操作,調動很多線程來並行處理請求,這樣會使得應用程序有更大的系統吞吐量。
1.1線程
線程是什麼呢?線程就是進程中的一條執行路徑,每個應用程序至少在一個線程上運行。在本篇中將會對線程稍作講解.
在.NET中,線程是執行的基本單元。在.NET中的線程並非是操作系統中的物理線程,而是對物理線程的托管代碼表示。
在.NET System.Threading命名空間下,有個Thread類型的類,它就是代表著托管線程。
1.2線程的創建
我們直接來看下線程創建的示例:
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中創建一個線程首先需要線程方法,什麼叫線程方法?首先線程是一個操作或是一組操作的表示,線程方法就是前面這句話中的【操作】。
這裡先看一下Thread類型的構造函數接受了一個ThreadStart類型的無參數委托,這個是好理解的。
線程創建了必須要顯示的調用它的Start()函數才能開始執行線程。調用Strat()函數是不會對當前線程造成阻塞的,就是說在調用了之後控制權會立刻的回到當前的線程的客戶端中。
1 public sealed class Thread 2 { 3 public void Suspend(); 4 public void Resume(); 5 …… 6 }
Suspend()方法是掛起線程的執行.
Resume()方法則是釋放掛起的線程,讓線程繼續執行在調用Suspend()方法的時候,是不會造成當前線程阻塞的,在調用後,控制權立即返回的,而且在要被掛起的線程中, 也不是被立即掛起的,而是在執行到一個安全點的時候,才會執行掛機操作的。什麼是安全點?舉個例子吧,假如要被掛起的線程中 正在執行一個函數的時候,外部被通知命令,要被掛起,這個時候線程是不會被掛起的,當這個函數執行完畢的時候,線程則會被掛起, 假設編輯器是把安全點插設在每個函數的末端的。
.NET中是不推薦我們使用這兩個函數的,因為會造成很多方面的不穩定。
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()是靜態函數,是一個阻塞調用並且使當前線程放棄CPU時間片,就是在休眠指定的時間後,控制權才會返回到調用的線程。
Thread.Sleep(20);//讓當前調用線程休眠20毫秒
Thread類還提供了另一種類似於休眠的操作:
1 public static void SpinWait(int iterations);
調用SpinWait()也是會造成當前阻塞的,但是當前線程不會放棄CPU時間片,而是在等待有限的時間(參數設置)後繼續執行, 這種函數是在可控的情況下才去這樣調用的,比如說當前線程要使用一個資源,而這個資源在被其他線程使用,那麼就可以使用 SpinWait()函數,在等待有限的時間後,再去讀取資源,如果資源還沒被其他線程釋放,當前線程也會繼續執行,所有這是用於可控的情況下的方法。
1.3.3 加入線程
Thread類的Join()方法可以讓一個線程等待另一個線程的終結。
這句定義什麼意思呢?說是說不清的,來看一下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 }
從上圖的結果再結合代碼看一下,就大概的清楚了Join的意思了,意義就是阻塞當前線程,等待子線程(ThreadingTest函數中的thread變量)執行完畢時,當前線程再執行。
1.3.4線程中止
調用Thread類型提供的Abort()方法可以中止線程的運行,並且被中止的線程會拋出一個ThreadAbortException類型的異常。下面的示例代碼會清晰的描述和示例代碼結果圖。
來看示例代碼:
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+"-子線程內部-" + 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("當前線程"); 36 } 37 38 }
將在下一章講解線程同步。
作者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面