public class MyClass
{
public void DoSomething()
{
Lock(this)
{
//Do Something.
}
}
}
public class AnotherClass
{
MyClass myclass = new MyClass();
Public void DoAnotherThing()
{
lock(myclass)
{
Myclass.DoSomething();
}
}
}
这会造成僵局吗?
根据我的理解和我读过的文章 - 它会。为什么? - 每当调用DoSomething()时,它将尝试获得一个锁并等待锁(myclass)被释放,从而导致死锁。如果我错了,请确认我的理解(也请求一点解释)并纠正我。
答案 0 :(得分:1)
我认为您阅读的文章试图告诉您的是,您不应该lock (this)
,因为其他一些代码也可能会尝试锁定同一个对象。只有涉及两个或多个线程时才会发生这种情况。
这里有一些演示死锁问题的示例代码。尝试运行它并查看结果。
然后在lock (this)
行上进行修改,然后重试。
发生死锁是因为类的某些代码OUTSIDE类锁定在该类用于锁定的INSIDE类的同一个实例上 - 并且没有仔细的文档和可见性,这是一种真正的可能性。
这个故事的寓意是,一般来说,你不应该锁定在课堂外可见的任何东西(除非你仔细记录如何使用该课程的锁定),你永远不应该lock (this)
。< / p>
using System;
using System.Threading.Tasks;
namespace Demo
{
class MyClass
{
public void DoSomething()
{
Console.WriteLine("Attempting to enter the DoSomething lock.");
lock (this) // Change to lock(_locker) to prevent the deadlock.
{
Console.WriteLine("In the DoSomething lock.");
}
}
readonly object _locker = new object();
}
internal static class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
lock (myClass)
{
var task = Task.Run(() => myClass.DoSomething());
Console.WriteLine("Waiting for the task to complete.");
if (!task.Wait(1000))
Console.WriteLine("ERROR: The task did not complete.");
else
Console.WriteLine("Task completed.");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
}
}
答案 1 :(得分:0)
这不能创建死锁,因为只涉及一个线程。是的,如果已锁定MyClass
对象,则会锁定它。但是C#锁是&#34;递归&#34;,这意味着单个线程可以在同一个对象上保存多个锁,结果就像它只保持最外面的锁一样:内部锁立即成功,并且对象被锁定,直到最后一个锁被释放。 (在你被迫使用一种没有它的语言之前,你真的不明白这是多么有用。)
但我同意上面的每个人:lock(this)
是坏juju。