lock与C#多线程多线程
lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,而后释放该锁。简单讲就相似于 你去银行办理业务,一个柜台一次只能操做觉得客户,而若是你要到这个柜台办理业务就必须等前面的人的业务完成,而彼此之间不会有交集。下面经过具体的代码来深刻说明: 测试
using System; using System.Threading; namespace LockTest { class Program { static void Main() { Test test = new Test(); Thread one = new Thread(test.ThreadOne); //线程一调用test的 ThreadOne 方法
Thread two = new Thread(test.ThreadTwo); //线程而调用test的 ThreadTwo 方法
one.Start(); //启动线程一
two.Start(); //启动线程二
Console.ReadKey(); } } class LockTest { public int Number { get; set; } = 10; public void Print() { Console.WriteLine("The number is " + Number); } } class Test { private readonly LockTest _lockTest = new LockTest(); //用于测试的对象
public void ThreadOne() { //在此方法内锁定 _lockTest 所引用的对象并执行相应操做,在操做执行完之前不会释放次对象
lock (_lockTest) { Console.WriteLine("The object has been locked!"); Thread.Sleep(5000); //让当前线程休眠 5s
_lockTest.Number = 200; Console.Write("ThreadOne: "); _lockTest.Print(); } //操做完成并释放对象
Console.WriteLine("The object has been released!"); } public void ThreadTwo() {
//Console.WriteLine(_lockTest.Number); _lockTest.Number = 100;
//Console.WriteLine(_lockTest.Number); //锁定 _lockTest 所引用的对象 //若是要保证 lock 正常工做,全部对 _lockTest 的操做都要使用 lock 锁定 //好比上面 _lockTest.Number=100; 在 lock 外面,那么它将不受约束(便可以强制访问 _lockTest) //若是在上面语句后加 Console.WriteLine(_lockTest.Number); 那么将输出 100 而不是 200 (也不是 10)
lock (_lockTest) {
//_lockTest.Number=100; Console.Write("ThreadTwo: "); _lockTest.Print(); } } } }
运行上面的代码会发如今ThreadTwo 方法里的 lock内的代码 时有明显的延迟,即必须等到ThreadOne运行完成了才继续执行 lock内部的代码,并且输出的结果是200而不是100,说明 lock 外面的代码不会发生任何延迟。若是把 _lockTest.Number=100; 语句放在lock内部,会发现结果变成了 100 。 ui
经过上面的例子能够看出要保证 lock 正确工做,要对每一个 _lockTest 的操做加上 lock锁定 。而在程序运行的时候,会根据线程访问次对象的前后顺序来为每一个线程排序,且只有排在前面的线程对对象的操做完成了后面的对象才能访问此对象。
spa