【问题标题】:Why should i pass object to lock keyword while synchronizing [closed]为什么我应该在同步时将对象传递给锁定关键字[关闭]
【发布时间】:2016-01-23 22:57:29
【问题描述】:
object c = new object();
lock(c)
{
}

为什么我应该在同步上面的代码时将对象传递给 lock 关键字。如果我还传递它将在哪里使用。我知道它用于获取该对象的锁定。但我想知道我们如何获取锁定深入对象。线程如何释放我们在lock关键字中传递的对象上的锁。

【问题讨论】:

标签: c# multithreading monitor


【解决方案1】:

您不需要将锁定限制为 Object 对象,例如,您可以锁定 Dictionary 对象,以防止其他线程从集合中添加或删除。

如果不想使用 lock 关键字,可以使用 [MethodImpl(MethodImplOptions.Synchronized)]

例如。

 [MethodImpl(MethodImplOptions.Synchronized)]
 static void mySynchronisedTask()
 {
     //do things that i want to be synchronised
     Console.WriteLine("before sync task");
     Thread.Sleep(5000);
     Console.WriteLine("after sync task");
 }

【讨论】:

  • 首先,字典是一个对象。其次,虽然这是可能的,但如果字典是公开的,这实际上是一个坏主意。通过锁定公众可以访问的东西,这意味着您无法控制的代码可能会被锁定。这反过来又会由于争用而导致性能问题,或者由于死锁而导致正确性问题。这也意味着您将来可以灵活地更改锁定策略。最安全的做法是只锁定专用于锁定的私有对象。
  • 我还忘了提到 CLR 实现已针对 only-used-as-a-lock-object 场景进行了优化。
  • @EricLippert 我们可以在任何地方阅读有关该优化的信息吗?
  • @YuvalItzchakov stackoverflow.com/questions/1803298/… 同步块可以有多种用途。 clr 假设任何给定的对象都不太可能需要同步块来处理两件事。
  • 我不想传递任何对象。我想在不传递对象的情况下进行同步。为什么需要同步对象。在 java 中,我们直接使用“同步”进行同步。我猜我们不会在那里传递对象
【解决方案2】:

lock 语句是使用Monitor 方法进行线程同步的语法糖。 Monitor 表示某个资源上的独占锁,而在.NET 中,资源 是一个对象

为什么需要为Monitor 提供对象引用?好吧,因为你想在多线程环境中同步对整个对象的访问。

线程如何释放我们传入锁的对象上的锁 关键字?

想想lock如下:

Monitor.Enter(obj);

try
{
    // This would be the code inside the "lock" block
}
finally
{
    if(Monitor.IsEntered(obj))
       Monitor.Exit(obj); // <-- This is how a Monitor releases the lock
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    相关资源
    最近更新 更多