标签:
上来先看MSDN关于lock的叙述:
lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。 下面的示例包含一个 lock 语句。
lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
线程处理(C# 和 Visual Basic) 这节讨论了线程处理。
lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。
通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。 常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
• 如果实例可以被公共访问,将出现 lock (this) 问题。
• 如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
• 由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。
最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
在 lock 语句的正文不能使用 等待 关键字。
通读上面叙述后,再来几个事例看看:
例一:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace NB.Demo 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Test t = new Test(); 14 Thread[] threads = new Thread[10]; 15 for (int i = 0; i < threads.Length; i++) 16 { 17 18 threads[i] = new Thread(() => 19 { 20 t.Print(); 21 }); 22 23 threads[i].Name = "thread" + i; 24 25 } 26 27 for (int i = 0; i < threads.Length; i++) 28 { 29 threads[i].Start(); 30 } 31 32 Console.Read(); 33 } 34 } 35 class MyLock 36 { 37 public int Id { get; set; } 38 } 39 40 class Test 41 { 42 public void Print() 43 { 44 MyLock myLock = new MyLock(); 45 lock (myLock) 46 { 47 for (int i = 0; i < 10; i++) 48 { 49 Console.WriteLine("\t" + Thread.CurrentThread.Name.ToString() + "\t" + i.ToString() + " "); 50 } 51 } 52 } 53 } 54 }
输出结果: 线程出现了争抢,这不是我们想要的结果,我们预期是每次只有一个线程去执行Print方法。
例二:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace NB.Demo 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Test t = new Test(); 14 Test t0 = new Test(); 15 Thread[] threads = new Thread[10]; 16 for (int i = 0; i < threads.Length; i++) 17 { 18 19 threads[i] = new Thread(() => 20 { 21 t.Print(); 22 t0.Print(); 23 }); 24 25 threads[i].Name = "thread" + i; 26 27 } 28 29 for (int i = 0; i < threads.Length; i++) 30 { 31 threads[i].Start(); 32 } 33 34 Console.Read(); 35 } 36 } 37 class MyLock 38 { 39 public int Id { get; set; } 40 } 41 42 class Test 43 { 44 public void Print() 45 { 46 lock (this) 47 { 48 49 for (int i = 0; i < 10; i++) 50 { 51 Console.WriteLine("\t" + Thread.CurrentThread.Name.ToString() + "\t" + i.ToString() + " "); 52 } 53 } 54 } 55 } 56 }
输出结果: 同样线程出现了争抢,这不是我们想要的结果。
例三:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace NB.Demo 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Test t = new Test(); 14 15 Thread[] threads = new Thread[10]; 16 for (int i = 0; i < threads.Length; i++) 17 { 18 19 threads[i] = new Thread(() => 20 { 21 t.Print(); 22 }); 23 24 threads[i].Name = "thread" + i; 25 26 } 27 28 for (int i = 0; i < threads.Length; i++) 29 { 30 threads[i].Start(); 31 } 32 33 Console.Read(); 34 } 35 } 36 class MyLock 37 { 38 public int Id { get; set; } 39 } 40 41 class Test 42 { 43 MyLock myobj = new MyLock(); 44 public void Print() 45 { 46 lock (myobj) 47 { 48 49 for (int i = 0; i < 10; i++) 50 { 51 Console.WriteLine("\t" + Thread.CurrentThread.Name.ToString() + "\t" + i.ToString() + " "); 52 } 53 } 54 } 55 } 56 }
例四:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace NB.Demo 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Test t = new Test(); 14 15 Thread[] threads = new Thread[10]; 16 for (int i = 0; i < threads.Length; i++) 17 { 18 19 threads[i] = new Thread(() => 20 { 21 t.Print(); 22 }); 23 24 threads[i].Name = "thread" + i; 25 26 } 27 28 for (int i = 0; i < threads.Length; i++) 29 { 30 threads[i].Start(); 31 } 32 33 Console.Read(); 34 } 35 } 36 class MyLock 37 { 38 public int Id { get; set; } 39 } 40 41 class Test 42 { 43 private static object obj = new object(); 44 public void Print() 45 { 46 lock (obj) 47 { 48 49 for (int i = 0; i < 10; i++) 50 { 51 Console.WriteLine("\t" + Thread.CurrentThread.Name.ToString() + "\t" + i.ToString() + " "); 52 } 53 } 54 } 55 } 56 }
标签:
原文地址:http://www.cnblogs.com/startpoint/p/4338794.html