设置俩个 共享对象 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这种过期写法