C# 面试题 目录

C# 中什么是死锁 (deadlock)?如何避免?

推荐答案

在C#中,死锁(deadlock)是指两个或多个线程在执行过程中,因为争夺资源而造成的一种互相等待的现象,导致这些线程都无法继续执行下去。死锁通常发生在多个线程同时持有某些资源,并且都在等待对方释放资源的情况下。

避免死锁的常见方法:

  1. 避免嵌套锁:尽量减少在持有锁的情况下再去获取其他锁。
  2. 锁的顺序:确保所有线程以相同的顺序获取锁。
  3. 使用超时机制:在获取锁时设置超时时间,避免无限期等待。
  4. 使用Monitor.TryEnter:尝试获取锁,如果获取失败则放弃,避免阻塞。
  5. 使用lock语句:确保锁的范围尽可能小,减少锁的持有时间。

本题详细解读

死锁的产生条件

死锁的产生通常需要满足以下四个条件(称为死锁的四个必要条件):

  1. 互斥条件:资源一次只能被一个线程占用。
  2. 占有并等待:线程持有至少一个资源,并且正在等待获取其他被占用的资源。
  3. 非抢占条件:已经分配给线程的资源,不能被其他线程强行抢占,必须由线程自行释放。
  4. 循环等待条件:存在一个线程等待的循环链,每个线程都在等待下一个线程所占用的资源。

示例代码

以下是一个典型的死锁示例:

-- -------------------- ---- -------
------ ----- - --- ---------
------ ----- - --- ---------

---- ---------
-
    ---- -------
    -
        ------------------ -- ------
        ---- -------
        -
            -------------------------- -------- ---- --------
        -
    -
-

---- ---------
-
    ---- -------
    -
        ------------------ -- ------
        ---- -------
        -
            -------------------------- -------- ---- --------
        -
    -
-

------ -- - --- ----------------
------ -- - --- ----------------

-----------
-----------

----------
----------

在这个例子中,Thread1Thread2分别持有lock1lock2,并且都在等待对方释放锁,从而导致死锁。

如何避免死锁

  1. 锁的顺序:确保所有线程以相同的顺序获取锁。例如,修改上面的代码,让Thread2也先获取lock1,再获取lock2
-- -------------------- ---- -------
---- ---------
-
    ---- -------
    -
        ------------------ -- ------
        ---- -------
        -
            -------------------------- -------- ---- --------
        -
    -
-
  1. 使用Monitor.TryEnter:通过尝试获取锁并设置超时时间,避免无限期等待。
-- -------------------- ---- -------
---- ---------
-
    -- ------------------------ ----- -- -----------------
    -
        ---
        -
            ------------------ -- ------
            -- ------------------------ ----- -- -----------------
            -
                ---
                -
                    -------------------------- -------- ---- --------
                -
                -------
                -
                    --------------------
                -
            -
        -
        -------
        -
            --------------------
        -
    -
-

通过以上方法,可以有效避免死锁的发生。

纠错
反馈