为什么lock比Monitor.TryEnter慢得多?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (50)

结果

lock:85.3微秒

Monitor.TryEnter:11.0微秒

1000次迭代的结果:

lock:103.3微秒

Monitor.TryEnter:20.2微秒

为什么?

    [Test]
    public void Lock_Performance_Test()
    {
        const int lockIterations = 100;

        Stopwatch csLock = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; )
        {
            lock (object1)
            {
                i++;
            }
        }
        csLock.Stop();

        Stopwatch csMonitor = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; )
        {
            if (Monitor.TryEnter(object1, TimeSpan.FromSeconds(10)))
            {
                try
                {
                    i++;
                }
                finally
                {
                    Monitor.Exit(object1);
                }
            }
        }
        csMonitor.Stop();

        Console.WriteLine("Lock: {0:f1} microseconds", csLock.Elapsed.Ticks / 10M);
        Console.WriteLine("Monitor.TryEnter: {0:f1} microseconds", csMonitor.Elapsed.Ticks / 10M);;
    }
提问于
用户回答回答于

我实际上并不知道答案,但认为指出这一点很重要,lockMonitor.TryEnter在功能上相同。 lock语句类似于Monitor.Enter,这不会潜在地阻塞。诚然,在你的示例代码中,不应该有任何阻塞问题; 但我会保证,因为lock提供了阻塞,所以它比可以TryEnter做更多的工作(可能)。

在我的机器上试过你的代码,并得到完全不同的结果:

100次迭代: lock4.4微秒 Monitor.TryEnter:16.1微秒 Monitor.Enter:3.9微秒

100000次迭代: lock2872.5微秒 Monitor.TryEnter:5226.6微秒 Monitor.Enter:2432.9微秒

实际上,我在VS 2010中尝试过这样做,既针对.NET 3.5又针对.NET 4.0,虽然结果不同,但事实上lock都胜过Monitor.TryEnter

用户回答回答于

100太少了,而且在测试框架中运行可能会偏离。

以在4.0中会有不同的结果。

我得到:

lock: 3548ms
Monitor.TryEnter: 7008ms
Monitor.TryEnter (2): 2947ms
Monitor.Enter: 2906ms

测试台:

using System;
using System.Diagnostics;
using System.Threading;
static class Program {
    static void Main()
    {
        const int lockIterations = 50000000;
        object object1 = new object();
        lock (object1) { Console.WriteLine("First one has to pay an extra toll"); }
        Stopwatch csLock = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; ) {
            lock (object1) { i++; }
        }
        csLock.Stop();
        Console.WriteLine("lock: " + csLock.ElapsedMilliseconds + "ms");

        Stopwatch csMonitorTryEnter = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; ) {
            if (Monitor.TryEnter(object1, TimeSpan.FromSeconds(10))) {
                try { i++; } finally { Monitor.Exit(object1); }
            }
        }
        csMonitorTryEnter.Stop();
        Console.WriteLine("Monitor.TryEnter: " + csMonitorTryEnter.ElapsedMilliseconds + "ms");

        csMonitorTryEnter = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; ) {
            if (Monitor.TryEnter(object1, 10000)) {
                try { i++; } finally { Monitor.Exit(object1); }
            }
        }
        csMonitorTryEnter.Stop();
        Console.WriteLine("Monitor.TryEnter (2): " + csMonitorTryEnter.ElapsedMilliseconds + "ms");

        Stopwatch csMonitorEnter = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; ) {
            Monitor.Enter(object1);
            try { i++; } finally { Monitor.Exit(object1); }
        }
        csMonitorEnter.Stop();
        Console.WriteLine("Monitor.Enter: " + csMonitorEnter.ElapsedMilliseconds + "ms");
    }
}

所属标签

可能回答问题的人

  • 应用案例分享

    1 粉丝490 提问4 回答
  • 找虫虫

    5 粉丝0 提问3 回答
  • 桑先生

    14 粉丝0 提问3 回答
  • 嗨喽你好

    8 粉丝480 提问3 回答

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动