本文和大家分享一下浅谈C# 中的lock 方法与Monitor 类的关系_以及同步与互斥. 从上图被标注的区域可以看到:一条lock 语句被编译成了调用Monitor 的Enter 和Exit 的方法。 文章来自学IT网:http://www./cshare/show-8814-1.aspx
C 关于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 的区域 } catch (Exception e) { // 异常处理代码 } finally { //解除锁定 System.Threading.Monitor.Exit(obj); } }} Monitor 类的示例二: class Program3{ static void Main(string[] args) { //多个线程调用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方法设置一个锁定超时 if (Monitor.TryEnter(obj, 2000)) { try { Console.WriteLine("等待4秒开始"); Thread.Sleep(4000); Console.WriteLine("等待4秒结束"); } finally { //解除锁定 Monitor.Exit(obj); } } else { Console.WriteLine("已超时2秒!"); } }} D 关于同步与互斥 关于同步的问题,可以使用Monitor 类来解决。 在使用Monitor 类的时候,建议将Monitor.Enter( ) 方法替换成Monitor.TryEnter( ) 方法。 使用Monitor.Enter( ) 方法时,代码如下: Monitor.Entry(lockObj);try{ // lockObj的同步区}catch(Exception e){ // 异常处理代码}finally{ Monitor.Exit(lockObj); // 解除锁定}注意:如果直接在C#源程序中使用Monitor类,就必须调用Exit方法来显式地解除锁定。 使用Monitor.TryEnter( ) 方法时,代码如下: if(Monitor.TryEntry(lockObj, 1000)){ try { } finally { Monitor.Exit(lockObj); }}else{ // 超时后的处理代码}注意:使用TryEntry方法设置一个锁定超时,单位是毫秒。 上面的代码设置了锁定超时时间为1秒。 如果在1秒钟之内,lockObj 还未被解锁,TryEntry 方法就会返回 false; 如果在1秒钟之内,lockObj 被解锁,TryEntry 方法就会返回 true。 这样,可以使用TryEntry 方法来避免死锁。 文章来自学IT网: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); }}结果如下: 同步与互斥 示例二: 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); }}结果如下: 参考文章: 浅谈c#中使用lock的是与非 作者:Jeff Wong 同步技术之Monitor 作者:银河使者 示例下载 文章来自学IT网:http://www./cshare/show-8814-3.aspx
|
|
来自: kittywei > 《111.34-线程》