【问题标题】:How thread lock works when modifying an object item in a thread safe object collection through reference通过引用修改线程安全对象集合中的对象项时线程锁的工作原理
【发布时间】:2015-05-19 15:14:32
【问题描述】:

我有一个线程安全的对象集合,例如 c# 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();

非常感谢任何建议。

标签: c# multithreading synchronization thread-safety memorycache


【解决方案1】:

但是如果我通过更新集合中对象项的属性 参考,首先,它是线程安全的吗?

没有。

同步是如何工作的?

不会有同步写读/写属性。

是否会锁定每一行属性更新?

没有。

【讨论】:

  • 感谢 dugas,但是当我运行测试代码(如上)时,它给出了线程安全的结果。那会怎么样?
  • @JustinMathew 你是如何验证结果的?
  • 有几个原因可能会让您得到正确的结果(例如单核 cpu、cpu 架构、内存模型等)。您的示例绝对不是线程安全的。
  • @Servy - 我不确定我的测试是否正确,我做了什么,我创建了三个线程来计算一个属性(Val1)的总和并在之后得到正确的总和执行。你能不能告诉我 ?我如何证明它不是线程安全的。
猜你喜欢
  • 2016-05-15
  • 2011-05-23
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
相关资源
最近更新 更多