<一>,不是并行结束的,对于cpu来讲,一个时间内,只能执行一条指令,不可能执行多条。所以,对于多线程来讲,只是分了多个时间片,并不是一个时间内并行的执行多个指令。多线程并不是要两个线程同步的进行执行,就比较赛跑一样,两个人跑就行了,但不并需要每次都同时跨步。
<二>争夺锁应该是线程中并发的,但是这种并发对于cpu来讲,到了指令的原子级,还是有先后的。所以,对于一个对象实例来讲,最终只会有一个线程获取锁。<三>应该是其它线程对gM1调用了set而引发了解锁。你可以将其它线程都停下,看看是否就会阻塞。

解决方案 »

  1.   

    谢谢,第二点还是不怎么明白...第三点更本就.....违反了,gM1只能让一个线程进入的最最基本的原子的原则啊?(gM1.WaitOne( );,连续两次,注意,是连续的,而且是两次,第二次怎么可能不阻塞啊!)
      

  2.   

    執行緒和執行緒處理請參閱
    同步處理多執行緒處理的資料 | 執行緒共用 | ThreadPool
    作業系統使用處理序來分隔它們正在執行的不同應用程式。執行緒是作業系統分配處理器時間的基本單元,而一處理序中可有多個執行緒執行程式碼。每個執行緒都維護例外處理常式 (Exception Handler)、排程優先權,以及系統用來在執行緒排程之前儲存其內容的一組結構。執行緒內容包含執行緒在執行緒之主處理序的位址空間中順利繼續執行所需的所有資訊,其中包括執行緒的一組 CPU 暫存器和堆疊。.NET Framework 進一步將作業系統處理序細分為輕量的 Managed 子處理序,稱為應用程式定義域,由 System.AppDomain 表示。一或多個 Managed 執行緒 (由 System.Threading.Thread 表示) 可在相同 Unmanaged 處理序內一或數個應用程式定義域中執行。雖然每個應用程式定義域是由單一執行緒所啟動,但應用程式定義域中的程式碼可建立其他應用程式定義域和其他執行緒。結果是,Managed 執行緒可在同樣 Unmanaged 處理序中的各個應用程式定義域之間自由移動;而您只能有一個執行緒在數個應用程式定義域之間移動。支援先佔式多工的作業系統能夠從多個處理序產生同時執行多個執行緒的效果。方法是將可用的處理器時間分給需要它的執行緒,依序將處理序時間量分配給每個執行緒。目前執行的執行緒會在分配給它的時間量超過時暫止,同時另一個執行緒則繼續執行。當系統從一執行緒切換至另一執行緒時,它會儲存先佔執行緒的執行緒內容,然後重新載入執行緒佇列中下一個執行緒的已存執行緒內容。時間量的長度則要視作業系統和處理器而定。由於每段時間極短,因此即使只有一個處理器,多個執行緒看起來還是像同時執行一樣。這就是多處理器系統上的實際狀況,其中可執行的執行緒會在可用的處理器中散發。何時使用多個執行緒
    需要使用者互動的軟體必須儘快回應使用者的活動,以便提供豐富的使用者經驗。不過,同時它也必須執行需要的計算以儘快提供使用者資料。如果您的應用程式只使用一個執行緒,您可將非同步程式設計和 .NET 遠端處理或使用 ASP.NET 建立的 XML Web Service 加以結合,如此在使用本身的處理時間之外還可加上其他電腦的處理時間,藉此增加對使用者的回應性並減少您的應用程式處理資料的時間。如果您是執行耗用大量的輸出入 (I/O) 工作,您也可使用 I/O 完成通訊埠來增加應用程式的回應速度。多執行緒的優點
    不過,使用多個執行緒是現行最能夠增加對使用者的回應速度,而且又能幾乎同時處理完成工作所需的資料。在具有一個處理器的電腦上,多個執行緒利用使用者事件之間的短暫時間來在背景 (Background) 處理資料就可達到這種效果。例如,使用者可在另一個執行緒重新計算試算表其他部份時,在同一應用程式內編輯試算表。在相同的條件下,當在具有多個處理器的電腦上執行時,相同的應用程式會大幅提升使用者的滿意度。您的單一應用程式定義域可使用多個執行緒來完成下列工作: 在網路上與 Web 伺服器和資料庫通訊。 
    執行需耗用大量時間的作業。 
    區分不同優先權的工作。例如,高優先權執行緒處理時間緊急的工作,而低優先權執行緒執行其他工作。 
    允許使用者介面保持回應性,同時將時間分配給背景工作。 
    多執行緒的缺點
    建議您儘量少用執行緒,這樣可使作業系統資源的使用量降到最低並增進效能。當您設計應用程式時,也應將執行緒處理的資源需求和可能發生的衝突列入考量。資源需求如下: 系統會為處理序、AppDomain 物件和執行緒所需的內容資訊耗用記憶體。因此,可以建立的處理序、AppDomain 物件和執行緒數量就會受到可用記憶體的限制。 
    記錄大量執行緒會耗用相當多的處理器時間。如果同時有太多執行緒,則其中多數的進度會相當緩慢。如果目前的執行緒大都在同一處理序中,則排到其他處理序中執行緒的機會就會減少。 
    控制其中使用許多執行緒的程式碼執行是相當複雜的一件事,而且可能會產生許多錯誤。 
    您需要知道終結執行緒時可能發生何種情況,並知道如何處理。 
    提供資源的共用存取可能會產生衝突。若要避免衝突發生,您必須同步或控制共用資源的存取。無法適當同步存取 (無論是在相同或不同的應用程式定義域中) 可能會引發死結 (兩個執行緒停止回應來等候對方完成工作) 和競爭情形 (因未預期且嚴重依賴兩事件執行時間而發生的異常結果)。系統提供可用來協調多個執行緒之間資源共用的同步物件 (Synchronization Object)。減少執行緒的數量會使同步處理資源更為容易。需要同步的資源包括: 系統資源 (例如通訊連接埠)。 
    多個處理序共用的資源 (例如檔案控制代碼,File Handle)。 
    多個執行緒存取的單一應用程式定義域的資源 (例如全域、靜態和執行個體欄位)。 
    執行緒處理和應用程式設計
    一般來說,針對不會阻礙其他執行緒之相對而言較短時間的工作,以及當您的工作沒有特定排程時,使用 ThreadPool 類別是處理多個執行緒最簡單的方法。不過,要建立您自己的執行緒的原因如下: 如果您要使一項工作具有特定的優先權。 
    如果您要使一項工作可長期執行 (並因此而封鎖其他工作)。 
    如果您必須將執行緒置入單一執行緒 Apartment 中 (所有的 ThreadPool 執行緒均置於多執行緒 Apartment 中)。 
    如果您需要與執行緒關聯的穩定識別。例如,您應使用專用執行緒來中止、暫止或以名稱尋找它。 
    請參閱
    同步處理多執行緒處理的資料 | 執行緒共用 | ThreadPool
      

  3.   

    同步處理多執行緒處理的資料請參閱
    執行緒和執行緒處理 | Monitor | Interlocked | WaitHandle | ManualResetEvent | AutoResetEvent | ReaderWriterLock | SyncLock | lock | SynchronizationAttribute
    當多個執行緒可以呼叫單一物件的屬性 (Property) 和方法時,同步處理那些呼叫是很重要的。否則,一執行緒可能中斷另一執行緒正在執行的動作,而物件可能會成為無效狀態。類別的成員若能免於這種中斷,這個類別就稱為安全執行緒。Common Language Infrastructure 提供幾個策略,以同步處理對個體與靜態成員的存取: 同步內容 - 您可使用 SynchronizationAttribute 來為 ContextBoundObject 物件啟動簡單且自動的同步處理。 
    Synchronized 屬性 - 少數類別 (如 Hashtable 和 Queue) 會提供 Synchronized 屬性 (Property),以傳回類別執行個體的安全執行緒包裝函式。請參閱集合和同步處理 (執行緒安全)。 
    同步程式碼區域 - 您可使用 Monitor 類別或這個類別的編譯器 (Compiler) 支援,只針對需要同步的程式碼區塊進行處理,以增進效能。 
    手動同步處理 - 您可使用各種同步物件來建立您自己的同步辦法。 
    Common Language Runtime 提供將類別分為幾種的執行緒模型,可根據需求以各種不同方式同步處理。下表說明指定同步分類提供欄位和方法的同步支援。分類 全域欄位 靜態欄位 靜態方法 執行個體欄位 執行個體方法 特定程式碼區塊 
    無同步處理 否 否 否 否 否 否 
    同步內容 否 否 否 是 是 否 
    同步程式碼區域 否 否 標記的才有 否 標記的才有 標記的才有 
    手動同步 手動 手動 手動 手動 手動 手動 無同步處理
    這是物件的預設值。任何執行緒可隨時存取任何方法或欄位。只有一個執行緒應存取這些物件。同步內容
    您可在任何 ContextBoundObject 上使用 SynchronizationAttribute 來同步處理所有執行個體方法和欄位。同一內容領域中的所有物件都共用相同的鎖定。多個執行緒可存取方法和欄位,不過只能以一次一個執行緒的方式進行。同步程式碼區域
    您可使用 Monitor 類別或編譯器關鍵字來同步處理程式碼區塊、執行個體方法和靜態方法。同步靜態欄位則無支援。Visual Basic 和 C# 都支援使用特定語言關鍵字來標記程式碼區塊。產生的程式碼會在程式碼執行時嘗試取得鎖定。如果已取得鎖定,正在執行的程式碼會等候直到鎖定可用為止。當程式碼退出同步的程式碼區塊時,就會釋出鎖定。您也可使用 MethodImplAttribute 並傳遞 MethodImplOptions.Synchronized 來裝飾方法,如此產生的結果基本上與使用 Monitor 或 Monitor 程式碼區塊的任一編譯器關鍵字是相同的。Thread.Interrupt 可用來中斷執行緒繼續進行區塊化作業,例如等候存取同步程式碼區域。Thread.Interrupt 也可用來中斷執行緒繼續進行作業,例如 Thread.Sleep。Monitor 類別支援下列程式碼區塊同步處理: 同步執行個體方法。在執行個體方法上,目前物件 (在 C# 中為 this 關鍵字,在 Visual Basic 中則為 Me 關鍵字) 是用來進行同步處理。 
    同步靜態方法。在靜態方法上,類別是用來進行同步處理。 
    編譯器支援
    Visual Basic 和 C# 都支援使用 Monitor.Enter 和 Monitor.Exit 鎖定物件的語言關鍵字。Visual Basic 支援 SyncLock 陳述式;C# 支援 lock 陳述式。在這兩種情況下,如果程式碼區塊中擲回例外狀況 (Exception),lock 會取得鎖定或是 SyncLock 會自動釋出。C# 和 Visual Basic 編譯器會發出 try/finally 區塊,其中 Monitor.Enter 在 try 的開頭,而 Monitor.Exit 在 finally 區塊中。如果 lock 或 SyncLock 區塊中擲回例外狀況,則會執行 finally 處理常式來允許您進行任何清除工作。手動同步
    您可使用同步類別 Interlocked、Monitor、ReaderWriterLock、ManualResetEvent 和 AutoResetEvent 來取得和釋出要保護全域、靜態和執行個體欄位以及全域、靜態和執行個體方法的鎖定。如需詳細資訊,請參閱執行緒處理物件和功能。