多執行緒三種鎖Monitor,lock,Mutex

2022-02-16 12:13:06 字數 2457 閱讀 7221

c#中使用monitor類、lock和mutex類來同步多執行緒的執行

在多執行緒中,為了使資料保持一致性必須要對資料或是訪問資料的函式 加鎖,在資料庫中這是很常見的,但是在程式中由於大部分都是單執行緒的程式,所以沒有加鎖的必要,但是在多執行緒中,為了保持資料的同步,一定要加鎖,好在 framework中已經為我們提供了三個加鎖的機制,分別是monitor類、lock關鍵字和mutex類。

例如下面程式:由於這種程式都是毫秒級的,所以執行下面的程式可能在不同的機器上有不同的結果,在同一臺機器上不同時刻執行也有不同的結果,我的測試環境為vs2005, windowsxp , cpu3.0 , 1 g monery。

程式中有兩個執行緒thread1、thread2和乙個testfunc函式,testfunc會列印出呼叫它的執行緒名和呼叫的時間(mm級的),兩個執行緒分別以30mm和100mm來呼叫testfunc這個函式。testfunc執行的時間為50mm。程式如下:

using

system;

using

system.collections.generic;

using

system.text;

using

system.threading;

namespace

monitorlockmutex

public program()

public

void runthread()

private

void thread1func()

}private

void thread2func()

}private

void testfunc(string str)

", str, system.datetime.now.millisecond.tostring());

thread.sleep(50);}}

}執行結果如下:

可以看出如果不加鎖的話,這兩個執行緒基本上是按照各自的時間間隔+testfunc 的執行時間(50mm)對testfunc函式進行讀取。因為執行緒在開始時需要分配記憶體,所以第0次的呼叫不準確,從第1~9次的呼叫可以看 出,thread1的執行間隔約是80mm,thread2的執行間隔約是150mm。

現在將testfunc修改如下:

private

void testfunc(string str)

", str, system.datetime.now.millisecond.tostring());

thread.sleep(50);}}

或者是用monitor也是一樣的,如下:

private

void testfunc(string str)

", str, system.datetime.now.millisecond.tostring());

thread.sleep(50);

monitor.exit(this);

}其中enter和exit都是monitor中的靜態方法。

執行lock結果如下:

讓我們分析一下結果,同樣從第1次開始。相同執行緒間的呼叫時間間隔 為執行緒執行時間+testfunc呼叫時間,不同執行緒間的呼叫時間間隔為testfunc呼叫時間。例如:連續兩次呼叫thread1之間的時間間隔約為 30+50=80;連續兩次呼叫thread2之間的時間間隔約為100+50=150mm。呼叫thread1和thread2之間的時間間隔為 50mm。因為testfunc被lock住了,所以乙個thread呼叫testfunc後,當其它的執行緒也同時呼叫testfunc時,後來的執行緒即 進被排到等待佇列中等待,直到擁有訪問權的執行緒釋放這個資源為止。

這就是鎖定被呼叫函式的特性,即只能保證每次被乙個執行緒呼叫,執行緒優先順序高的呼叫的次數就多,低的就少,這就是所謂的強佔式。

下面讓我們看看mutex類的使用方法,以及與monitor和lock的區別。

將**修改如下:

private

void thread1func()

}private

void thread2func()

}private

void testfunc(string str)

", str, system.datetime.now.millisecond.tostring());

thread.sleep(50);

}執行結果如下:

可以看出,mutex只能互斥執行緒間的呼叫,但是不能互斥本執行緒的 重複呼叫,即thread1中waitone()只對thread2中的waitone()起到互斥的作用,但是thread1並不受本 wainone()的影響,可以呼叫多次,只是在呼叫結束後呼叫相同次數的releasemutex()就可以了。

那麼如何使執行緒按照呼叫順序來依次執行呢?其實把lock和mutex結合起來使用就可以了,改**如下:

private

void thread1func()}}

private

void thread2func()}}

多執行緒的三種特性

是指乙個操作是不可中斷的。即使是多個執行緒一起執行的時候,乙個操作一旦開始,就不會被其他執行緒干擾。比如,對於乙個靜態全域性變數int i,兩個執行緒同時對它賦值,執行緒a給他賦值為1,執行緒b給他賦值為 1。那麼不管這兩個執行緒 以何種方式。何種步調工作,i的值要麼是1,要麼是 1.執行緒a和執行...

java多執行緒三種方式

有三種 1 繼承thread類,重寫run函式 建立 class xx extends thread 開啟執行緒 物件.start 啟動執行緒,run函式執行 2 實現runnable介面,重寫run函式 開啟執行緒 thread t new thread 物件 建立執行緒物件 t.start 3 ...

建立多執行緒的三種方式

首先需要理解清楚程式 程序 執行緒 程式 即靜態的 塊 程序 執行中的程序 執行緒 程序的進一部細分,程式的一條執行路徑 第一種 建立乙個類繼承thread,並重寫run 方法 第一種方法 建立乙個繼承thread的子類 class subthread extends thread public c...