Как работает блокировка потока при изменении элемента объекта в потокобезопасной коллекции объектов по ссылке

У меня есть потокобезопасная коллекция объектов, например, С# MemoryCache. Как мы знаем, такие операции, как добавление, обновление и удаление элементов в этой коллекции, безопасны. Но если я обновлю свойства элемента объекта в коллекции через ссылку, во-первых, будет ли это потокобезопасно? как работает синхронизация? будет ли заблокирована каждая строка обновления свойства?

class MyClass
{
     public int Val1 { get; set; }
     public int Val2 { get; set; }
}

class Program
{

    public static MemoryCache MyCache = new MemoryCache("test");

    static void Main(string[] args)
    {


        MyCache.Add("1", new MyClass() {Val1 = 0, Val2 = 0}, new CacheItemPolicy());

        new Thread(() => {

            MyClass item = (MyClass)MyCache["1"];                
            for (int i = 0; i < 100000; i++)
            {
                item.Val1 =  item.Val1 + i;
            }

        }).Start();

        new Thread(() =>
        {
            MyClass item = (MyClass)MyCache["1"];
            for (int i = 100000; i < 200000; i++)
            {
                item.Val1 =  item.Val1 + i;
            }
        }).Start();

любой совет действительно ценится.


person Justin Mathew    schedule 19.05.2015    source источник
comment
У вас уже есть код для проверки. Что произошло, когда вы запустили его?   -  person Servy    schedule 19.05.2015
comment
Результат выглядит безопасным для потоков. Но я читал в нескольких блогах, что это не так, поэтому просто хочу проверить больше комментариев.   -  person Justin Mathew    schedule 19.05.2015
comment
Значит, вы знали ответ на свой вопрос еще до того, как его задали? Тогда зачем вы задавали вопрос, если вы уже знали ответ?   -  person Servy    schedule 19.05.2015
comment
@SriramSakthivel Он заявляет, что провел свое исследование, обнаружил, что это небезопасно, предположил, что это безопасно, несмотря на то, что ему сказали, что это не так, спросил еще раз, и ему сказали, что он уже нашел раньше, что это небезопасно.   -  person Servy    schedule 19.05.2015


Ответы (1)


Но если я обновлю свойства элемента объекта в коллекции через ссылку, во-первых, будет ли это потокобезопасно?

No.

как работает синхронизация?

Не будет синхронизации записи чтения/записи свойства.

будет ли заблокирована каждая строка обновления свойства?

No.

person dugas    schedule 19.05.2015
comment
Спасибо dugas, но когда я запустил тестовый код (см. выше), он дал потокобезопасный результат. Как это было бы? - person Justin Mathew; 19.05.2015
comment
@JustinMathew Как вы проверяли результат? - person Servy; 19.05.2015
comment
Есть несколько причин, по которым вы могли получить правильный результат (например, одноядерный процессор, архитектура процессора, модель памяти и т. д.). Ваш пример абсолютно не потокобезопасен. - person dugas; 19.05.2015
comment
@Servy - я не уверен, что мой тест правильный или нет, что я и сделал, я создал три потока, чтобы выполнить сумму одного свойства (Val1) и получить правильную сумму после выполнения. Не могли бы вы мне сказать ? как я могу доказать, что это не потокобезопасно. - person Justin Mathew; 20.05.2015