Почему блокировки выполняются на отдельных объектах?

Возможный дубликат:
Разница между блокировкой (locker) и блокировкой (variable_which_I_am_using)

Во всех примерах кода, "невидочных", которые я видел, они блокируют отдельный объект-заглушку. Почему прямая блокировка выполняется непосредственно над данными?

Ответы

Ответ 1

Блокировка на отдельном объекте private дает гарантию, что никто не блокирует этот объект.

Если вы заблокируете данные, и тот же самый фрагмент данных будет виден снаружи, вы потеряете эту гарантию. Например:

public class MyObject
{
    public void SharedMethod()
    {
        lock (this)
        {
            // Do stuff
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyObject o = new MyObject();

        lock (o)
        {
            new Thread(() =>
            {
                // Gets blocked 2s because of external lock
                o.SharedMethod();
            }).Start();

            Thread.Sleep(2000);
        }
    }
}

Ответ 2

Джефф Рихтер (автор CLR Via С#) объясняет, почему в этой статье Безопасная синхронизация потоков.

В частности, в этой статье раздел "Почему Великая идея не так велика" отвечает на ваш вопрос.

На самом деле это глава из книги CLR Via С#.

Таким образом, наличие частного объекта в качестве объекта "synclock" позволяет вашему классу инкапсулировать и контролировать любую блокировку ваших потребностей класса. Поэтому независимо от того, сколько клиентов использует ваш класс, блокировка выполняется последовательно и правильно.

Ответ 3

Там есть что-то замечательное в блоге Эрика Гуннерса. См. здесь и здесь.