概念
什麼是執行緒?每個正在系統上運行的程式都是一個進程。每個進程包含一到多個執行緒。進程也可能是整個程式或者是部分程式的動態執行。執行緒是一組指令的集合,或者是程式的特殊段,它可以在程式里獨立執行。也可以把它理解為代碼運行的上下文。所以執行緒基本上是輕量級的進程,它負責在單個程式里執行多任務。通常由作業系統負責多個執行緒的調度和執行。
什麼是多執行緒?
多執行緒是為了使得多個執行緒並行的工作以完成多項任務,以提高系統的效率。執行緒是在同一時間需要完成多項任務的時候被實現的。
執行緒
定義
英文:Thread
每個正在系統上運行的程式都是一個進程。每個進程包含一到多個執行緒。進程也可能是整個程式或者是部分程式的動態執行。執行緒是一組指令的集合,或者是程式的特殊段,它可以在程式里獨立執行。也可以把它理解為代碼運行的上下文。所以執行緒基本上是輕量級的進程,它負責在單個程式里執行多任務。通常由作業系統負責多個執行緒的調度和執行。
執行緒是程式中一個單一的順序控制流程.在單個程式中同時運行多個執行緒完成不同的工作,稱為多執行緒.
執行緒和進程的區別在於,子進程和父進程有不同的代碼和數據空間,而多個執行緒則共享數據空間,每個執行緒有自己的執行堆疊和程式計數器為其執行上下文.多執行緒主要是為了節約CPU時間,發揮利用,根據具體情況而定.執行緒的運行中需要使用計算機的記憶體資源和CPU。
好處
使用執行緒的好處有以下幾點:
使用執行緒可以把占據長時間的程式中的任務放到後台去處理
用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度
程式的運行速度可能加快
在一些等待的任務實現上如用戶輸入、檔案讀寫和網路收發數據等,執行緒就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如記憶體占用等等。
還有其他很多使用多執行緒的好處,這裡就不一一說明了。
一些執行緒模型的背景
我們可以重點討論一下在Win32環境中常用的一些模型。
單線程模型
在這種執行緒模型中,一個進程中只能有一個執行緒,剩下的親必須等待當前的執行緒執行完。這種模型的缺點在於系統完成一個很小的任務都必須占用很長的時間。
塊執行緒模型(單執行緒多塊模型STA)
這種模型里,一個程式里可能會包含多個執行的執行緒。在這裡,每個執行緒被分為進程里一個單獨的塊。每個進程可以含有多個塊,可以共享多個塊中的數據。程式規定了每個塊中執行緒的執行時間。所有的請求通過Windows訊息佇列進行串列化,這樣保證了每個時刻只能訪問一個塊,因而只有一個單獨的進程可以在某一個時刻得到執行。這種模型比單執行緒模型的好處在於,可以回響同一時刻的多個用戶請求的任務而不只是單個用戶請求。但它的性能還不是很好,因為它使用了串列化的執行緒模型,任務是一個接一個得到執行的。
多執行緒塊模型(自由執行緒塊模型)
多執行緒塊模型(MTA)在每個進程里只有一個塊而不是多個塊。這單個塊控制著多個執行緒而不是單個執行緒。這裡不需要訊息佇列,因為所有的執行緒都是相同的塊的一個部分,並且可以共享。這樣的程式比單執行緒模型和STA的執行速度都要塊,因為降低了系統的負載,因而可以最佳化來減少系統idle的時間。這些應用程式一般比較複雜,因為程式設計師必須提供執行緒同步以保證執行緒不會並發的請求相同的資源,因而導致競爭情況的發生。這裡有必要提供一個鎖機制。但是這樣也許會導致系統死鎖的發生。
多執行緒在.NET里如何工作?
NET Framework
在本質上和結構來說,.NET是一個多執行緒的環境。有兩種主要的多執行緒方法是.NET所提倡的:使用ThreadStart來開始你自己的進程,直接的(使用ThreadPool.QueueUserWorkItem)或者間接的(比如Stream.BeginRead,或者調用BeginInvoke)使用ThreadPool類。一般來說,你可以"手動"為長時間運行的任務創建一個新的執行緒,另外對於短時間運行的任務尤其是經常需要開始的那些,進程池是一個非常好的選擇。進程池可以同時運行多個任務,還可以使用框架類。對於資源緊缺需要進行同步的情況來說,它可以限制某一時刻只允許一個執行緒訪問資源。這種情況可以視為給執行緒實現了鎖機制。執行緒的基類是System.Threading。所有執行緒通過CLI來進行管理。
創建執行緒:
創建一個新的Thread對象的實例。Thread的構造函式接受一個參數:
Thread DummyThread = new Thread( new ThreadStart(dummyFunction) );
執行執行緒:
使用Threading命名空間裡的start方法來運行執行緒:
DummyThread.Start ();
組合執行緒:
經常會出現需要組合多個執行緒的情況,就是當某個執行緒需要其他執行緒的結束來完成自己的任務。假設DummyThread必須等待DummyPriorityThread來完成自己的任務,我們只需要這樣做:
DummyPriorityThread.Join() ;
暫停執行緒:
使得執行緒暫停給定的秒
DummyPriorityThread.Sleep(<Time in Second>);
中止執行緒:
如果需要中止執行緒可以使用如下的代碼:
DummyPriorityThread.Abort();
同步
經常我們會遇到需要線上程間進行同步的情況,下面的代碼給出了一些方法:
using System;using System.Threading;namespace SynchronizationThreadsExample{
class SynchronizationThreadsExample{
private int counter = 0;
static void Main( ) {
SynchronizationThreadsExample STE = new SynchronizationThreadsExample();
STE.ThreadFunction( );
}
public void ThreadFunction ( ) {
使用Interlock
C#提供了一個特殊的類叫做interlocked,就是提供了鎖機制的實現,我們可以加入如下的代碼實現鎖機制:
Interlocked.SomeFunction (ref counter);
使用鎖
這是為了鎖定代碼關鍵區域以進行同步,鎖定代碼如下:
lock (this){ Some statements ;}
使用Monitor
當有需要進行執行緒管理的時候我們可以使用:
Monitor.Enter(this);
其他也有一些方法進行管理,這裡就不一一提及了。
執行緒的缺點
執行緒自然也有缺點,以下列出了一些:
如果有大量的執行緒,會影響性能,因為操作系統需要在他們之間切換;
·更多的執行緒需要更多的記憶體空間
執行緒會給程式帶來更多的bug,因此要小心使用
執行緒的中止需要考慮其對程式運行的影響
通常塊模型數據是在多個執行緒間共享的,需要一個合適的鎖系統替換掉數據共享
Java
Java對多執行緒的支持是非常強大的,他禁止掉了許多的技術細節,讓我們可以輕鬆的開發多執行緒的套用程式。
Java裡面實現多執行緒,有2個方法
參考連結:
/wiki/http://hi.baidu.com/ce%255Fken/blog/item/c7e7ebc40fe265ca39db49a7.html
/wiki/http://hi.baidu.com/ce%255Fken/blog/item/70c5670f62592a2b6159f348.html