想象一下这段代码:
你有两个阵列,你需要在同一时刻锁定它们(出于任何原因 - 你只需要保持锁定它们两个因为它们以某种方式相互依赖) - 你可以嵌套锁
lock (array1)
{
lock (array2)
{
... do your code
}
}
但是如果代码的其他部分中有人会这样做,这可能会导致死锁
lock (array2)
{
lock (array1)
{
... do your code
}
}
并且数组1被锁定 - 执行上下文切换 - 然后数组2被第二个线程锁定。
有没有办法以原子方式锁定它们?比如
lock_array(array1, array2)
{
....
}
我知道我可以创建一些额外的“锁定对象”并在我的代码中锁定而不是两个数组,但这对我来说似乎不正确......
答案 0 :(得分:5)
通常,您应该避免锁定可公开访问的成员(在您的情况下为数组)。你宁愿让private static object
锁定。
答案 1 :(得分:4)
如Darin所说,你永远不应该允许锁定可公开访问的变量。例如
public class Foo
{
public object Locker = new object();
}
public class Bar
{
public void DoStuff()
{
var foo = new Foo();
lock(foo.Locker)
{
// doing something here
}
}
}
而是做这样的事情。
public class Foo
{
private List<int> toBeProtected = new List<int>();
private object locker = new object();
public void Add(int value)
{
lock(locker)
{
toBeProtected.Add(value);
}
}
}
这样做的原因是,如果您有多个线程访问多个公共同步构造,则运行非常真实的死锁可能性。然后你必须非常小心你的编码方式。如果您正在向其他人提供您的图书馆,您可以确定您可以获得锁定吗?也许有人使用你的库也抓住了锁,你们两个之间已经陷入了死锁的境地。这就是Microsoft建议不使用SyncRoot的原因。
答案 2 :(得分:1)
我不确定锁定数组是什么意思。 您可以在单个锁中轻松地对两个阵列执行操作。
static readonly object a = new object();
lock(a){
//Perform operation on both arrays
}