4

图像此代码:

你有 2 个数组,你需要同时锁定它们(出于任何原因 - 你只需要保持锁定它们,因为它们以某种方式相互依赖) - 你可以嵌套锁

lock (array1)
{
    lock (array2)
    {
        ... do your code
    }
}

但这可能会导致死锁,以防您代码的其他部分中的某人会这样做

lock (array2)
{
    lock (array1)
    {
        ... do your code
    }
}

并且数组 1 被锁定 - 执行上下文切换 - 然后数组 2 被第二个线程锁定。

有没有办法原子地锁定它们?如

lock_array(array1, array2)
{
    ....
}

我知道我可以创建一些额外的“锁定对象”并锁定它,而不是在我的代码中到处都是两个数组,但这对我来说似乎不正确......

4

3 回答 3

5

一般来说,您应该避免锁定可公开访问的成员(您的情况下的数组)。你宁愿有一个private static object你会锁定的。

于 2013-05-21T08:01:08.273 回答
4

正如达林所说,你永远不应该允许锁定可公开访问的变量。例如

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 的原因。

于 2013-05-21T08:06:52.530 回答
1

我不确定您所说的锁定数组是什么意思。您可以轻松地在单个锁中对两个阵列执行操作。

static readonly object a = new object();
lock(a){
    //Perform operation on both arrays
    }
于 2013-05-21T08:05:00.453 回答