通过多个线程读取/写入引用类型字段WITHOUT lock

时间:2010-06-21 09:53:22

标签: .net multithreading locking

上下文:高度线程化的服务器端应用程序,包含许多读取,偶尔写入。

让我们考虑以下简单代码:

[Serializable]
public class BusinessObject
{
    // ... lot's of stuff, all READ ONLY!!!
}

public class BusinessObjectHost
{
    private BusinessObject bo;
    public BusinessObject BO
    {
       get { return this.bo; }
       set { this.bo = value; }
    }

}

预期用途如下:BusinessObject是不可变的。如果我偶尔想要更改它,我只需要用新实例替换BusinessObjectHost.bo字段。

Q1:如果我在BusinessObjectHost.BO属性中不应用任何锁会发生什么情况,并且BusinessObjectHost.bo字段上的读写之间存在线程冲突? 线程会抛出异常吗?如果是的话,哪一个?

Q2:如果线程崩溃导致异常,以下代码是否有效?

public class BusinessObjectHost
{
    private BusinessObject bo;
    public BusinessObject BO
    {
       get 
       { 
           int i = 5; // Max 5 tries
           while (i-- > 0)
           {
              try { return this.bo; }
              catch (WhateverThreadConflictException) {}
           }
           throw new MyException(); 
       }
       set 
       { 
           int i = 5; // Max 5 tries
           while (i-- > 0)
           {
              try { this.bo = value; return; }
              catch (WhateverThreadConflictException) {}
           }
           throw new MyException(); 
       }
    }

}

问题3:如果上述解决方案不好,您会推荐什么?

2 个答案:

答案 0 :(得分:3)

您的BusinessObjectHost仅包含引用。引用是原子的,因此您不会使用snippet1中的简单代码获得异常。

使用它可能是可以接受的,具体取决于您想要发生的事情。当两个或多个线程现在读取BO属性时,它们可能会获得对不同实例的引用。但是无论如何你都无法阻止BO属性代码。

Q2,Q3:snippet2中的代码无法解决任何问题。

答案 1 :(得分:0)

我相信.NET为这个目的提供了一个类。

ReaderWriterLock Class http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx