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

本文关键字:对象 代码 两个 | 更新日期: 2023-09-27 18:25:34

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

object lockObject = new object();
// Thread 1
void Method1()
{
    lock(lockObject)
    {
        // task1
    }
}
// Thread 2
void Method2()
{
    lock(lockObject)
    {
        // task2
    }
}

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

是的,您可以用两种不同的方法使用同一个锁对象(从技术上讲,它是计算机科学意义上的监视器,通过调用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
        }
    }
}

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

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

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

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

你可以而且有效。如果不使用同一个对象,那么这些块可能会同时执行。如果你确实使用了同一个对象,他们就不能。

另外,你指的是lock(lockObject),而不是using(lockObject)