C# 多线程 Lock 锁
码云Lock 展示1.概念
临界区:一块代码在时间片段里,只能有一个线程访问。
Lock 关键字:将语句标记为临界区,上锁,执行语句,释放锁。
互斥锁(Mutex):访问的代码块被暂用,那线程就睡觉去了,等着被叫醒干活。
自旋锁:访问的代码块被暂用,那么该线程就一直在这块等着,砸门,敲门,骂街一个劲的让在锁里的线程快点出来,在外等的线程要急着进去。自旋锁不能执行长时间的任务。跟着急上厕所一样的。
object.ReferenceEquals方法是肯定是引用判等,判断该代码块是不是被锁定了。
1 2 3 4 5 6 | // lock (1) int 不是lock 语句要求的引用类型 // (object)1 跟本就没有锁住,线程交叉,数据混乱。数据在线程中交叉用。最后抛错了 // null System.ArgumentNullException:“Value cannot be null.” Monitor 直接报错了 // thisLock 私有静态只读 内存中独一份,且不会被更改,所以每次线程来查看是否代码块被锁住,用的就是object.ReferenceEquals方法 // 对象类中有个区块存放锁信息,再根据Lock() 中的对象地址判断是不是同一块地址。如果是同一块地址那么就是互斥锁,只能一个线程进入 // 如果对比值为false 那么就认为不是互斥锁,其他线程也可以进入操作。 |
static void TestThreadLockThis() { TestLockThis TestLockThis = new TestLockThis(); //在t1线程中调用LockMe,并将deadlock设为true(将出现死锁) Thread t1 = new Thread(TestLockThis.LockMethod); t1.Name = " 子线程 执行"; t1.Start(true); Thread.Sleep(100); Thread.CurrentThread.Name = "主线程来也"; //在主线程中lock c1 lock (TestLockThis) { //调用没有被lock的方法 TestLockThis.NotLockMethod(); //调用被lock的方法,并试图将deadlock解除 TestLockThis.LockMethod(false); } } public class TestLockThis { private bool deadlocked = true; private static readonly object lockobject = new object(); //这个方法用到了lock,我们希望lock的代码在同一时刻只能由一个线程访问 public void LockMethod(object o) { //lock (this) //整个类被锁住,必须等待子线程t1 执行完,才能让主线程执行 lock (lockobject) //互斥锁,该代码块被锁住,主线程可以访问这个类的NotLockMethod(),子线程t1一直在执行所以等待子线程执行完后 //主线程将其设置为 deadlocked =false; { while (deadlocked) { deadlocked = (bool)o; Console.WriteLine($"I am locked 是{Thread.CurrentThread.Name}"); Thread.Sleep(600); } } } //所有线程都可以同时访问的方法 public void NotLockMethod() { Console.WriteLine($"I am not locked 是{Thread.CurrentThread.Name}"); } }
Lock(this) 是将这个类锁定,刚开始线程t1 访问到LockMethod 后,发现是Lock(this),只有t1线程能进入,后来主线程睡眠醒了后访问lock这个类被锁,所以进不去。结果是也没有打印到I am not locked
Lock(lockObject) 代码块锁定,主线程可以访问NotLockMethod() 方法,但是要访问LockMethod方法,需要等t1线程执行完后。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?