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 那么就认为不是互斥锁,其他线程也可以进入操作。

  码云Lock展示

复制代码
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线程执行完后。
posted @   蘇州澄湖  阅读(626)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示