C# 多线程基础 锁 死锁 Monitor lock

发布于:2025-02-10 ⋅ 阅读:(110) ⋅ 点赞:(0)

设置俩个 共享对象 lock1 lock2 模拟竞争情况
在主线程和子线程 分别使用 monitor 以及 lock 对这俩个对象 分别上锁以及使用
通过 net 8控制台代码实例 看下效果 讲解在代码后

class Program
{

    static void Main(string[] args)
    {
        object lock1 = new object();
        object lock2 = new object();

        new Thread(() => LockOther(lock1, lock2)).Start();

        lock (lock2)
        {
            Thread.Sleep(1000);
            Console.WriteLine("主线程使用Monitor.TryEnter获取锁lock1,获取超时释放");
            if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(3)))
            {
                Console.WriteLine("主线程Monitor拿到锁lock1");
            }
            else
            {
                Console.WriteLine("主线程Monitor没拿到锁lock1");
            }
        }


        Console.WriteLine("------------第二个案列---------------");
        new Thread(() => LockOther(lock1, lock2)).Start();

        lock (lock2)
        {
            Console.WriteLine("主线程使用lock,会出现死锁后面代码一直不执行");
            Thread.Sleep(2000);
            lock (lock1)
            {
                Console.WriteLine("主线程lock方式拿到锁lock1");
            }
        }

        Console.ReadKey();
    }

    static void LockOther(object lock1, object lock2)
    {
        Console.WriteLine("子线程开始 线程id:" + Thread.CurrentThread.ManagedThreadId);
        lock (lock1)
        {
            Console.WriteLine("子线程锁住lock1");
            Thread.Sleep(1000);
            lock (lock2)
            {
                Console.WriteLine("子线程锁住lock2");
            }

        }
        Console.WriteLine("锁结束");
    }


}

在这里插入图片描述

讲解
正常逻辑 主线程 子线程 在一开始分别 各锁住了一个对象 然后在各自业务中使用另一个对象
那么要使用另一个对象 必须等待释放

案列2
1:代码没有完全都执行 可以看出 在锁住另一个对象后的代码 像是卡住没办法执行了
2:这好像就是正常逻辑情况下会出现的情况 也就是 死锁的定义表现
3:通俗将就是 俩个人都各自锁住一个资源 而恰好 要使用的其他资源 都是对方所持有的,无限等待

案列1
1:第一个案列可以看到 所有的代码逻辑都执行了
2:可以看到主线程是没拿到锁lock1 的 正常逻辑也是子线程拥有的 肯定拿不到
3:说明了Monitor.TryEnter 使用在拿不到的情况下 过期时间会自动放弃获取

总结:
1.死锁 使用lock用法 在两方对于资源 各持有且其他引用无法释放无限等待情况
2.Monitor.TryEnter 提供过期时间 避免无限等待 解决死锁问题
3.lock 是Monitor 语法糖 但是并没提供 TryEnter这种过期写法


网站公告

今日签到

点亮在社区的每一天
去签到