在两个不同的代码块使用相同的锁对象?

Red*_*Fox 19 c# multithreading locking

我可以在两个方法中使用相同的锁对象,由两个不同的线程访问吗?目标是使task1和task2线程安全.

object lockObject = new object();

// Thread 1
void Method1()
{
    lock(lockObject)
    {
        // task1
    }
}

// Thread 2
void Method2()
{
    lock(lockObject)
    {
        // task2
    }
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*cin 22

是的,你可以用两种不同的方法使用相同的锁对象(技术上是计算机科学意义上的监视器,并通过调用System.Monitor中的方法实现).

所以,假设你有一些静态资源r,并且你想要两个线程来访问该资源,但是一次只能有一个线程使用它(这是锁的经典目标).然后你会写代码

public class Foo
{
    private static object _LOCK = new object();

    public void Method1()
    {
        lock (_LOCK)
        {
            // Use resource r
        }
    }

    public void Method2()
    {
        lock (_LOCK)
        {
            // Use resource r
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要锁定r程序中的每个用法,否则两个线程可以同时使用r.此外,您必须使用相同的锁,否则两个线程将同时使用r.因此,如果您使用r两种不同的方法,则必须使用两种方法中的相同锁定.

编辑:正如@diev在评论中指出的那样,如果资源是类型对象上的每个实例Foo,我们就不会生成_LOCK静态,而是生成_LOCK实例级数据.

  • 您应该明确指出锁对象是“静态”这一事实,因此它所保护的资源也应该是“静态”;如果 r 是实例级别上可用的资源,则实例级别锁定对象可能会更好。 (2认同)

pho*_*oog 5

如果要防止不同的线程同时执行task1和task2,则必须使用相同的锁定对象.

如果这两个任务不争用相同的资源,则可以使用不同的锁定对象.


Ry-*_*Ry- 5

是的。

你可以,它的工作原理。如果您不使用相同的对象,则块可以同时执行。如果您确实使用相同的对象,则它们不能。

另外,你的意思是lock(lockObject),不是using(lockObject)