写在前面:
在多线程编程中,可能会有许多线程并发的执行一段代码。在某些情况下,我们希望A中的代码块(B)同步的执行,即同一时刻只有一个线程执行代码块B,这就需要用到锁(lock)。lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待,已达到安全访问。
举一个例子:现有十个苹果,张三和李四同时吃这些苹果
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace LockTest { class Program { private static int apple = 10;//10个苹果 static void Main(string[] args) { Thread t1 = new Thread(() => EatApple("张三")); Thread t2 = new Thread(() => EatApple("李四")); t1.IsBackground = true; t2.IsBackground = true; t1.Start(); t2.Start(); Console.ReadKey(); } private static void EatApple(string name) { while (true) { apple -= 1; Console.WriteLine(name + "正在吃苹果"); Thread.Sleep(3000); Console.WriteLine(name + "吃完了,还剩" + apple + "个苹果\n"); if (apple <= 0) break; } } } }
结果是这样的混乱:
然后我们把共同访问的代码加上锁之后:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace LockTest { class Program { private static int apple = 10; //10个苹果 private static object locker = new object();//创建锁 static void Main(string[] args) { Thread t1 = new Thread(() => EatApple("张三")); Thread t2 = new Thread(() => EatApple("李四")); t1.IsBackground = true; t2.IsBackground = true; t1.Start(); t2.Start(); Console.ReadKey(); } private static void EatApple(string name) { while (true) { lock (locker)//加锁 { apple -= 1; Console.WriteLine(name + "正在吃苹果"); Thread.Sleep(3000); Console.WriteLine(name + "吃完了,还剩" + apple + "个苹果\n"); if (apple <= 1)//变为1 不然会吃-1个苹果 break; } } } } }
结果如下,加上锁之后呢,两个人就只能一个人一个人的去拿苹果吃。
lock用法:
其写法如下: Object locker = new Object(); lock(locker) { //此处放置同步执行的代码 }
相当于:
private static object locker = new object();//创建锁 Monitor.Enter(locker); //排它锁 { //此处放置同步执行的代码 } Monitor.Exit(locker); //释放指定对象上的排他锁
原文地址:https://www.cnblogs.com/mexihq/p/12632290.html
时间: 2024-10-10 04:49:20