如何锁定几个对象?

jav*_*red 27 c#

我想同时锁定两个对象.为什么我不能像这样的代码写?

锁(obj1,obj2)

我应该这样写吗?

lock (obj1)
{
    lock (obj2)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能会变得更简单吗?可能最好引入特殊的私有对象并将其用于锁...

Her*_*nis 40

好吧,这个问题太旧了,但是,这是一个我认为是紧凑的问题,两个代码都将结束相同的编译语句(这和问题描述中的一个):

    lock (obj1) lock (obj2)
    {
        // your code
    }
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这只不过是省略第一个“lock”语句的可选大括号。使用“正确”缩进,第二个“lock”将位于新行并缩进一级。 (3认同)

Håv*_*d S 31

这是锁定多个对象的正确方法,是的.

我的猜测是,只允许锁定语句的单个参数的原因是使锁定的顺序尽可能清楚.

请注意,您必须确保在代码中的每个位置都以相同的顺序获取两个锁,否则您可能会出现死锁.

您也可以按照建议引入一个专用的锁定对象,但这会使您的锁定更加粗糙.这一切都取决于您的需求.如果您有时只需要其中一个锁,则应将它们分开(但请确保保留锁定顺序,如上所述).

  • 你对"到处都是同一个订单"的评论是黄金,我想在同一个两个账户A到B和B到A的两个电汇中,你会按字母顺序锁定例如所以你锁定A和B,不管是什么源帐户和目标帐户,否则锁定(A)锁定(B)和锁定(B)锁定(A)将会死锁,即使您执行仅涉及一个帐户的操作(如提款),它也能正常工作.我只是想在这里分享一个实际的例子,它让我疯了一会儿. (5认同)

Dan*_*rth 18

如果您编写这样的代码,您需要确保始终按此顺序锁定这两个对象.否则,您可能会遇到死锁.


fel*_*ult 5

我遇到了同样的问题,并编写了可能会帮助你的片段,即使它远非完美:

private void MultiLock(object[] locks, WaitCallback pFunc, int index = 0)
{
    if (index < locks.Count())
    {
        lock (locks[index])
        {
            MultiLock(locks, pFunc, index + 1);
        }
    }
    else
    {
        ThreadPool.QueueUserWorkItem(pFunc);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,只需调用此方法:

public object LockedObject1 = new Object();
public object LockedObject2 = new Object();

public void MyFunction(object arg)
{
    WaitCallback pFunc = delegate
    {
        // Operations on locked objects
    }

    MultiLock(new object[] {LockedObject1, LockedObject2}, pFunc);
}
Run Code Online (Sandbox Code Playgroud)