首頁 後端開發 C#.Net教程 C#的多線程機制初探(4)

C#的多線程機制初探(4)

Dec 21, 2016 pm 03:02 PM

exPRession代表你希望追蹤的對象,通常是對象引用。一般地,如果你想保護一個類別的實例,你可以使用this;如果你希望保護一個靜態變數(如互斥程式碼段在一個靜態方法內部),一般使用類別名稱就可以了。而statement_block就是互斥段的程式碼,這段程式碼在一個時刻內只可能被一個執行緒執行。

  以下是一個使用lock關鍵字的典型例子,我將在註釋裡向大家說明lock關鍵字的用法和用途:

//lock.cs 
using System; 
using. Threading;

internal class Account 
{ 
int balance; 
Random r = interdom);
 { 
balance = initial; 
}

internal int Withdraw(int amountmount if (balance { 
//如果balance小於0則拋出異常 
 } 
//下面的程式碼保證在當前線程修改balance的值完成之前 
//不會有其他線程也執行這段程式碼
//因此,balance的值是不可能小於0的 
lock (this) 
{ 
Console. WriteLine("Current Thread:"+Thread.CurrentThread.Name); 
//如果沒有lock關鍵字的保護,那麼可能在執行完單的條件判斷//另外一個線程卻執行了balance=balance-amount修改了balance的值 
///而這個修改對這個線程是不可見的,所以可能導致這時if的條件已經不成立了 
//但是,這個線程卻繼續執行balance=balance-amount,所以導致balance可能小於0 
=mount (
{ 
Thread.Sleep(5); 
 return amount; 
} 

 return 0; // transaction rejected 
} 
} { 
 for (int i = 0; i Withdraw(r.Next(-50, 100));
internal class Test 
{ 
static internal Thread[] threads = new Thread[10]; 
  Account acc = new Account (0); 
for (int i = 0; i  = new Thread(new ThreadStart(acc.DoTransactions)); 
threads[i] = t; 
  ; i threads[i].Name=i.ToString(); 
for (int i10; i threads[i].Start(); 
Console.ReadLine(); 
}也會出現和公用程式碼類似的問題,這種問題就不應該使用lock關鍵字了,這裡需要用到System.Threading中的一個類別Monitor,我們可以稱之為監視器,Monitor提供了讓線程共享資源的方案。

  Monitor類別可以鎖定一個對象,一個執行緒只有得到這把鎖才可以對該對象進行操作。物件鎖機制保證了在可能造成混亂的情況下一個時刻只有一個執行緒可以存取這個物件。 Monitor必須和一個具體的對象相關聯,但是由於它是一個靜態的類,所以不能使用它來定義對象,而且它的所有方法都是靜態的,不能使用對象來引用。以下程式碼說明了使用Monitor鎖定一個物件的情形:

...... 
Queue oQueue=new Queue(); 
...... 
Monitor.Enter(oQueueEnt ); 
......//現在oQueue物件只能被目前執行緒操縱了 
Monitor.Exit(oQueue);//釋放鎖

如上所示,當一個執行緒呼叫Monitor.Enter()方法鎖定一個物件時,這個物件就歸它所有了,其它執行緒想要存取這個對象,只有等待它使用Monitor.Exit()方法釋放鎖。為了確保執行緒最終都能釋放鎖,你可以把Monitor.Exit()方法寫在try-catch-finally結構中的finally程式碼區塊裡。對於任何一個被Monitor鎖定的對象,內存中都保存著與它相關的一些信息,其一是現在持有鎖的線程的引用,其二是一個預備隊列,隊列中保存了已經準備好獲取鎖的線程,其三是一個等待隊列,隊列中保存著當前正在等待這個物件狀態改變的隊列的引用。當擁有物件鎖的線程準備釋放鎖時,它使用Monitor.Pulse()方法通知等待佇列中的第一個線程,於是該線程被轉移到預備佇列中,當物件鎖被釋放時,在預備佇列中的執行緒可以立即獲得物件鎖。

下面是一個展示如何使用lock關鍵字和Monitor類別來實現線程的同步和通訊的例子,也是一個典型的生產者與消費者問題。在這個例程中,生產者線程和消費者線程是交替進行的,生產者寫入一個數,消費者立即讀取並且顯示,我將在註釋中介紹該程式的精要所在。使用到的系統命名空間如下:

using System; 
using System.Threading

 以上就是C#的多線程機制初探(4)的內容,更多相關內容請關注中文PHPwww. php.cn)! 


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用 C# 的活動目錄 使用 C# 的活動目錄 Sep 03, 2024 pm 03:33 PM

使用 C# 的 Active Directory 指南。在這裡,我們討論 Active Directory 在 C# 中的介紹和工作原理以及語法和範例。

C# 序列化 C# 序列化 Sep 03, 2024 pm 03:30 PM

C# 序列化指南。這裡我們分別討論C#序列化物件的介紹、步驟、工作原理和範例。

C# 中的隨機數產生器 C# 中的隨機數產生器 Sep 03, 2024 pm 03:34 PM

C# 隨機數產生器指南。在這裡,我們討論隨機數產生器的工作原理、偽隨機數和安全數的概念。

C# 資料網格視圖 C# 資料網格視圖 Sep 03, 2024 pm 03:32 PM

C# 資料網格視圖指南。在這裡,我們討論如何從 SQL 資料庫或 Excel 檔案載入和匯出資料網格視圖的範例。

C# 中的階乘 C# 中的階乘 Sep 03, 2024 pm 03:34 PM

C# 階乘指南。這裡我們討論 C# 中階乘的介紹以及不同的範例和程式碼實作。

C# 中的模式 C# 中的模式 Sep 03, 2024 pm 03:33 PM

C# 模式指南。在這裡,我們討論 C# 中模式的介紹和前 3 種類型,以及其範例和程式碼實作。

C# 中的質數 C# 中的質數 Sep 03, 2024 pm 03:35 PM

C# 質數指南。這裡我們討論c#中素數的介紹和範例以及程式碼實作。

c#多線程和異步的區別 c#多線程和異步的區別 Apr 03, 2025 pm 02:57 PM

多線程和異步的區別在於,多線程同時執行多個線程,而異步在不阻塞當前線程的情況下執行操作。多線程用於計算密集型任務,而異步用於用戶交互操作。多線程的優勢是提高計算性能,異步的優勢是不阻塞 UI 線程。選擇多線程還是異步取決於任務性質:計算密集型任務使用多線程,與外部資源交互且需要保持 UI 響應的任務使用異步。

See all articles