zoukankan      html  css  js  c++  java
  • c# 解决死锁问题Monitor

    前言

    在高并发中,一个很关键的问题就是要避免死锁。

    那么为什么会产生死锁呢?这种情况多见吗?

    举一个例子:

    比如方法一中先lock(object1),在lock(object1)中lock(object2)。

    方法二种则相反。

    那么这时候可以看出,如果方法一中lock了object1,这时候请求object2。

    方法二种lock了object2,这时候请求object1,那么这时候就出现问题了。

    这样解释不太明白,那么直接看代码吧。

    正文

    看下这个吧:

    static void Main(string[] args)
    {
    	object lock1 = new object();
    	object lock2 = new object();
    	new Thread(() => LockTooMuch(lock1, lock2)).Start();
    	lock (lock2)
    	{
    		Thread.Sleep(1000);
    		Console.WriteLine("try to get lock1");
    		if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5)))
    		{
    			Console.WriteLine("Acquired a protected resource succesfully");
    		}
    		else
    		{
    			Console.WriteLine("Time out  a resource");
    		}
    	}
    	Console.Read();
    }
    
    static void LockTooMuch(object lock1, object lock2)
    {
    	lock (lock1)
    	{
    		Thread.Sleep(1000);
    		lock (lock2) {
    			Console.WriteLine("enter lock2");
    		};
    	}
    }
    

    结果:

    这个是怎么运行的呢?

    主线程获取lock2,然后分支线程获取lock1,然后请求lock2。

    这时候就堵塞了,可以拿上面代码运行一下,会堵塞5秒。

    这个5秒怎么来的呢?if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5))) 这时候是尝试去获取lock1,

    因为lock1倍分支线程给获取了,那么获取不到,这时候等待5秒,5秒后获取不到就直接走了lese这条路,然后就释放了lock2,这时候分支线程就继续运行。

  • 相关阅读:
    动态类型
    unlink与close关系
    Google 历年笔试面试30题
    UNIX网络编程 卷2 源代码使用
    centos安装telnet
    python中安装第三方模块
    Linux平台 Oracle 18c RAC安装Part1:准备工作
    RHEL7 配置iSCSI模拟环境
    Solaris 10主机名和IP地址步骤
    设置sqlplus不显示除查询结果外的信息
  • 原文地址:https://www.cnblogs.com/aoximin/p/13224393.html
Copyright © 2011-2022 走看看