)中的示例**十,一樣如果多執行緒使用共享變數,就會涉及到乙個執行緒同步的問題。那如何解決呢?
方法有三:
1) 重構程式,移除多執行緒的共享變數,讓乙個執行緒只訪問乙個自有變數
2) 使用原子操作,乙個操作只占用乙個量子時間,一次完成,只有當當前操作完成之後,其他執行緒才能進行操作。這樣可以避免使用獨佔鎖,避免死鎖。
3) 通過net構架提供的mutex、autorestevent、countdowneven、spinwait等類,來進行執行緒間的同步。
usingsystem;
using
system.collections.generic;
using
system.linq;
using
system.text;
using system.threading; //
引入執行緒
using
system.diagnostics;
namespace
threadsynchronousdemo
", c.count));
console.writeline(
"----------------------------");
var c1 = new
counterinterlocked();
var t4 = new thread(() =>count(c1));
t4.name = "
執行緒4";
var t5 = new thread(() =>count(c1));
t5.name = "
執行緒5"
;
var t6 = new thread(() =>count(c1));
t6.name = "
執行緒6"
; t4.start();
t5.start();
t6.start();
t4.join();
t5.join();
t6.join();
console.writeline(
string.format("
interlocked的多執行緒總計:
二、使用mutex類
1. 接下來我們來學習使用mutex類來實現執行緒間的同步問題。
2. 在程式啟動時,設定initialowner
為false
,這表示如果互斥量已經建立,則允許程式獲取互斥量。如果沒有互斥量,則程式直接執行,等待接收任意鍵,然後釋放互斥量。
3.**如下:
using4.執行結果如下圖。system;
using
system.collections.generic;
using
system.linq;
using
system.text;
using system.threading; //
引入執行緒
using
system.diagnostics;
namespace
threadsynchronousdemo
else
}
console.read();}}
}
在debug目錄下,先執行主程式,如上圖中1,則程式1正常執行,此時如果再次開啟debug目錄下的應用主程式,則執行結果如上圖中2。說明互斥量起作用了。
5.先在上圖主程式1中輸入k,然後回車,結果如下圖中3。我們從debug目錄下,再次開啟應用程式,則應用程式的執行結果如下圖中4。說明主程式1,已經把互斥量釋放。
注意:具名互斥量是全域性的作業系統物件。請務必正確關閉互斥量。最好使用using來包裹互斥量**。這種方式可以在不同程式中同步執行緒。
三、使用semaphoreslim類
semaphoreslim是semaphore類的乙個輕量級版本。此類限制了同時訪問同一資源的執行緒數量。
在.net中,類semaphore封裝了clr中的核心同步物件。與標準的排他鎖物件(monitor,mutex,spinlock)不同的是,它不是乙個排他的鎖物件,它與semaphoreslim,readerwritelock等一樣允許多個有限的執行緒同時訪問共享記憶體資源。
semaphore就好像乙個柵欄,有一定的容量,當裡面的執行緒數量到達設定的最大值時候,就沒有執行緒可以進去。然後,如果乙個執行緒工作完成以後出來了,那下乙個執行緒就可以進去了。semaphore的waitone或release等操作分別將自動地遞減或者遞增訊號量的當前計數值。當執行緒試圖對計數值已經為0的訊號量執行waitone操作時,執行緒將阻塞直到計數值大於0。在構造semaphore時,最少需要2個引數。訊號量的初始容量和最大的容量。
1.程式**
using2.程式執行結果如下圖。system;
using
system.collections.generic;
using
system.linq;
using
system.text;
using system.threading; //
引入執行緒
using
system.diagnostics;
namespace
threadsynchronousdemo
console.read();
}static
void accessdatabase(string name,int
seconds)
等待訪問資料庫
", name);
semapslim.wait();
console.writeline(
" 被授予對資料庫的訪問許可權
", name);
thread.sleep(timespan.fromseconds(seconds));
console.writeline(
" 完成了
", name);
semapslim.release(); }}
}
當程式啟動時,建立了乙個semaphoreslim物件,並在建構函式中指定了併發的執行緒數量,然後啟動了10個不同名稱,不同初始執行時間的執行緒。
每個執行緒都嘗試獲取資料庫訪問許可權,但是我們使用semaphoreslim物件做了限制,只有5個執行緒能同時訪問資料庫,當前5個執行緒獲取了資料庫訪問許可權之後,剩下的5個執行緒只能等待,直到有執行緒完成工作,並呼叫semaphore的release方法。
多執行緒程式設計學習筆記 執行緒同步(二)
1.使用autoresetevent類來實現從乙個執行緒向另乙個執行緒發出通知。2.如下 using system using system.collections.generic using system.linq using system.text using system.threading ...
多執行緒程式設計 執行緒同步
同步,永遠是多執行緒程式設計中最核心和最重要的話題.同步相關的概念比如 臨界區,原子操作,以及互斥量等等 總的來說,在多個執行緒之間採取同步措施,無非是為了讓他們更好的協同工作或者維持共享資料的一致性.1.共享資料的一致性 實際上,保證共享資料一致性的最簡單且最好的方法,就是使得該資料成為乙個常量,...
多執行緒程式設計學習筆記 執行緒池(一)
接上文 多執行緒程式設計學習筆記 執行緒同步 一 接上文 多執行緒程式設計學習筆記 執行緒同步 二 接上文 多執行緒程式設計學習筆記 執行緒同步 三 建立多執行緒操作是非常昂貴的,所以每個執行時間非常短的操作,建立多執行緒進行操作,可能並不能提高效率,反而降低了效率。執行緒池,就是我們先分配一些資源...