Использовать один и тот же объект блокировки в двух разных блоках кода?

Можно ли использовать один и тот же объект блокировки двумя способами, доступ к которым осуществляется двумя разными потоками? Цель состоит в том, чтобы сделать thread1 и task2 безопасными.

object lockObject = new object();

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

// Thread 2
void Method2()
{
    lock(lockObject)
    {
        // task2
    }
}

Ответы

Ответ 1

Да, вы можете использовать один и тот же объект блокировки (это технически monitor в смысле компьютерной науки и реализуется с вызовами методов в 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 static, а делали бы _LOCK данные уровня экземпляра.

Ответ 2

Если вы хотите, чтобы разные потоки не выполняли задачи task1 и task2 одновременно, вы должны использовать один и тот же объект блокировки.

Если две задачи не противоречат тем же ресурсам, вы можете использовать разные блокирующие объекты.

Ответ 3

Да.

Вы можете и это работает. Если вы не используете один и тот же объект, блоки могут выполняться одновременно. Если вы используете один и тот же объект, они не могут.

Кроме того, вы имеете в виду lock(lockObject), а не using(lockObject).