本文和大家分享一下淺談C# 中的lock 方法與Monitor 類的關(guān)系_以及同步與互斥. 從上圖被標注的區(qū)域可以看到:一條lock 語句被編譯成了調(diào)用Monitor 的Enter 和Exit 的方法,。 文章來自學IT網(wǎng):http://www./cshare/show-8814-1.aspx
C 關(guān)于Monitor 類
● Monitor 類屬于System.Threading 命名空間,; ● Monitor 類提供同步對對象的訪問的機制; ● 使用 Monitor 鎖定對象(即引用類型)而不是值類型,; ● Monitor 類型對于多線程操作是安全的,; Monitor 類的示例一: class Program2{ static void Main(string[] args) { MyMonitor1 mon_1 = new MyMonitor1(); mon_1.Test(); }} class MyMonitor1{ private object obj = new object(); public void Test() { //開始鎖定 System.Threading.Monitor.Enter(obj); try { //lock 的區(qū)域 } catch (Exception e) { // 異常處理代碼 } finally { //解除鎖定 System.Threading.Monitor.Exit(obj); } }} Monitor 類的示例二: class Program3{ static void Main(string[] args) { //多個線程調(diào)用Test方法 Thread t1 = new Thread(MyMonitor2.Test); Thread t2 = new Thread(MyMonitor2.Test); t1.Start(); t2.Start(); }}class MyMonitor2{ private static object obj = new object(); public static void Test() { //使用TryEntry方法設(shè)置一個鎖定超時 if (Monitor.TryEnter(obj, 2000)) { try { Console.WriteLine("等待4秒開始"); Thread.Sleep(4000); Console.WriteLine("等待4秒結(jié)束"); } finally { //解除鎖定 Monitor.Exit(obj); } } else { Console.WriteLine("已超時2秒!"); } }} D 關(guān)于同步與互斥 關(guān)于同步的問題,,可以使用Monitor 類來解決,。 在使用Monitor 類的時候,建議將Monitor.Enter( ) 方法替換成Monitor.TryEnter( ) 方法,。 使用Monitor.Enter( ) 方法時,,代碼如下: Monitor.Entry(lockObj);try{ // lockObj的同步區(qū)}catch(Exception e){ // 異常處理代碼}finally{ Monitor.Exit(lockObj); // 解除鎖定}注意:如果直接在C#源程序中使用Monitor類,就必須調(diào)用Exit方法來顯式地解除鎖定,。 使用Monitor.TryEnter( ) 方法時,,代碼如下: if(Monitor.TryEntry(lockObj, 1000)){ try { } finally { Monitor.Exit(lockObj); }}else{ // 超時后的處理代碼}注意:使用TryEntry方法設(shè)置一個鎖定超時,單位是毫秒,。 上面的代碼設(shè)置了鎖定超時時間為1秒,。 如果在1秒鐘之內(nèi),lockObj 還未被解鎖,,TryEntry 方法就會返回 false,; 如果在1秒鐘之內(nèi),,lockObj 被解鎖,TryEntry 方法就會返回 true,。 這樣,,可以使用TryEntry 方法來避免死鎖。 文章來自學IT網(wǎng):http://www./cshare/show-8814-2.aspx
同步與互斥 示例一:
class Program4{ static void Main(string[] args) { Thread A = new Thread(TestClass1.GetA); A.Name = "Thread_A "; Thread B = new Thread(TestClass1.GetB); B.Name = "Thread_B "; A.Start(); B.Start(); }} class TestClass1{ private static object resource_A = new object(); private static object resource_B = new object(); public static void GetA() { MyWrite("in GetA()"); if (Monitor.TryEnter(resource_A, 2000)) { MyWrite("get resource_A"); GetB(); Thread.Sleep(2000); Monitor.Exit(resource_A); MyWrite("exit resource_A"); } else { MyWrite("no has resource_A"); } } public static void GetB() { MyWrite("in GetB()"); if (Monitor.TryEnter(resource_B, 1000)) { MyWrite("get resource_B"); GetA(); Thread.Sleep(1000); Monitor.Exit(resource_B); MyWrite("exit resource_B"); } else { MyWrite("no has resource_B"); } } //自定義打印方法 private static void MyWrite(string str) { Console.WriteLine(Thread.CurrentThread.Name + str); }}結(jié)果如下: 同步與互斥 示例二: class Program5{ static void Main(string[] args) { Thread A = new Thread(TestClass2.GetA); A.Name = "Thread_A "; Thread B = new Thread(TestClass2.GetB); B.Name = "Thread_B "; A.Start(); B.Start(); }} class TestClass2{ //排他鎖的對象 A private static object resource_A = new object(); //排他鎖的對象 B private static object resource_B = new object(); public static void GetA() { MyWrite("in GetA()"); if (Monitor.TryEnter(resource_A, 1000)) { MyWrite("get resource_A"); Thread.Sleep(1000); //GetB(); if (Monitor.TryEnter(resource_B, 2000)) { Monitor.Exit(resource_B); } Monitor.Exit(resource_A); MyWrite("exit resource_A"); } else { MyWrite("no has resource_A"); } } public static void GetB() { MyWrite("in GetB()"); if (Monitor.TryEnter(resource_B, 1000)) { MyWrite("get resource_B"); Thread.Sleep(1000); //GetA(); if (Monitor.TryEnter(resource_A, 2000)) { Monitor.Exit(resource_A); } Monitor.Exit(resource_B); MyWrite("exit resource_B"); } else { MyWrite("no has resource_B"); } } //自定義打印方法 private static void MyWrite(string str) { Console.WriteLine(Thread.CurrentThread.Name + str); }}結(jié)果如下: 參考文章: 淺談c#中使用lock的是與非 作者:Jeff Wong 同步技術(shù)之Monitor 作者:銀河使者 示例下載 文章來自學IT網(wǎng):http://www./cshare/show-8814-3.aspx
|
|
來自: kittywei > 《111.34-線程》