C#简单理解 lock

《下一篇:C# 简单理解 Monitor.Wait 与 Monitor.Pulse 》

事实上, lock 关键词的是一种语法糖,我们可以用如下C# 代码分析:

public class Test
{
    private object obj = new object();
    public int Method2()
    {
        lock(obj)
        {
            return 0;
        }
    }
}

生成 exe 分别用 ILSpy 看一下实际的代码:

.method public hidebysig 
    instance int32 Method2 () cil managed 
{
    // Method begins at RVA 0x209c
    // Code size 37 (0x25)
    .maxstack 2
    .locals init (
        [0] object,
        [1] bool,
        [2] int32
    )

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: ldfld object Demo.Test::obj
    IL_0007: stloc.0
    IL_0008: ldc.i4.0
    IL_0009: stloc.1
    .try
    {
        IL_000a: ldloc.0
        IL_000b: ldloca.s 1
        IL_000d: call void [mscorlib]System.Threading.Monitor::Enter(object, bool&)
        IL_0012: nop
        IL_0013: nop
        IL_0014: ldc.i4.0
        IL_0015: stloc.2
        IL_0016: leave.s IL_0023
    } // end .try
    finally
    {
        IL_0018: ldloc.1
        IL_0019: brfalse.s IL_0022

        IL_001b: ldloc.0
        IL_001c: call void [mscorlib]System.Threading.Monitor::Exit(object)
        IL_0021: nop

        IL_0022: endfinally
    } // end handler

    IL_0023: ldloc.2
    IL_0024: ret
} // end of method Test::Method2

随便看一个就可以知道 lock(obj)  { } ,相当于是在括号不封前后增加了 Monitor.Enter(obj,ref bool) 和 Monitor.Exit(obj),如果书写成代码可以看成是:

//一些要在 { } 进行处理的变量

bool isGetLock = false;
try
{
    Monitor.Enter(obj, ref isGetLock);

    //要执行的 { } 中的代码
    //主要是处理声明的变量
}
finally 
{
    if(isGetLock)
    {
        Monitor.Exit(obj);
    }
}

//如果有 return 就 return 返回相应的值

所以,如果使用了 lock 就无需担心程序由于没有捕获异常而退出 lock 的代码块,导致 lock 的对象没有被解锁。所以如下的代码是不必要的:

lock(obj)
{
    try
    {
    }
    catch
    {
    }
}

除非你真的需要去对这个异常进行处理。

posted @ 2019-11-29 00:54  霁雪湖上三映月  阅读(315)  评论(0)    收藏  举报