expression代表你希望跟蹤的物件,通常是物件引用。一般地,如果你想保護乙個類的例項,你可以使用this;如果你希望保護乙個靜態變數(如互斥**段在乙個靜態方法內部),一般使用類名就可以了。而statement_block就是互斥段的**,這段**在乙個時刻內只可能被乙個執行緒執行。
//lock.cs
using system;
using system.threading;
internal class account
internal int withdraw(int amount)
//下面的**保證在當前執行緒修改balance的值完成之前
//不會有其他執行緒也執行這段**來修改balance的值
//因此,balance的值是不可能小於0的
lock (this)
else
}
}
internal void dotransactions()
}
internal class test
for (int i = 0; i < 10; i++)
threads[i].name=i.tostring();
for (int i = 0; i < 10; i++)
threads[i].start();
console.readline();
}
}而多執行緒公用乙個物件時,也會出現和公用**類似的問題,這種問題就不應該使用lock關鍵字了,這裡需要用到system.threading中的乙個類monitor,我們可以稱之為監視器,monitor提供了使執行緒共享資源的方案。
monitor類可以鎖定乙個物件,乙個執行緒只有得到這把鎖才可以對該物件進行操作。物件鎖機制保證了在可能引起混亂的情況下乙個時刻只有乙個執行緒可以訪問這個物件。monitor必須和乙個具體的物件相關聯,但是由於它是乙個靜態的類,所以不能使用它來定義物件,而且它的所有方法都是靜態的,不能使用物件來引用。下面**說明了使用monitor鎖定乙個物件的情形:
......
queue oqueue=new queue();
......
monitor.enter(oqueue);
......//現在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 的多執行緒機制初探 2 C 教程
下面我們就動手來建立乙個執行緒,使用thread類建立執行緒時,只需提供執行緒入口即可。執行緒入口使程式知道該讓這個執行緒幹什麼事,在c 中,執行緒入口是通過threadstart delegate 來提供的,你可以把threadstart理解為乙個函式指標,指向執行緒要執行的函式,當呼叫threa...
C 的多執行緒機制初探 2
threadtest.cs using system using system.threading namespace threadtest public class catch threadstateexception return 0 這段程式包含兩個類alpha和 在建立執行緒othread時...
C 的多執行緒機制初探 3
在這裡我們要注意的是其它執行緒都是依附於main 函式所在的執行緒的,main 函式是c 程式的入口,起始執行緒可以稱之為主線程,如果所有的前台執行緒都停止了,那麼主線程可以終止,而所有的後台執行緒都將無條件終止。而所有的執行緒雖然在微觀上是序列執行的,但是在巨集觀上你完全可以認為它們在並行執行。讀...