多个属性的线程安全模式

时间:2013-02-19 18:49:24

标签: .net multithreading properties thread-safety

我有一个对象,它有大约15个String,decimal?,DateTime属性?还是int?。 我有一个从多个线程操作的这个类的集合。我想确保以线程安全的方式访问(读/写)对象属性的值,同时编写最少量的代码。 是否有这样的方式而不是使用私有支持者并在每个属性的getter和setter中进行显式锁定? 以下是我现在要为每个房产做的事情:

public class ManyProperties
{
    private Object mLock = new Object;
    private string _personName;
    public string PersonName {
        get {            
             lock (mLock){
                 return _personName;
             }           
        }
        set { 
             lock (mLock){
                  _personName = value; 
             }
        }
    }

    private string _beginAmount;
    public decimal? BeginAmount {
        get {            
             lock (mLock){
                 return _beginAmount;
             }           
        }
        set { 
             lock (mLock){
                  _beginAmount = value; 
             }
        }
    }
}

1 个答案:

答案 0 :(得分:4)

属性通常不会孤立地工作。如果您无法获得正确且有效的等值,那么让每个属性线程安全都无济于事。更合适的方法是使整个事物不可变,让调用者获得快照

public class ManyProperties
{
    private readonly string _personName;
    public string PersonName { get { return _personName; } }

    private readonly decimal? _beginAmount;
    public decimal? BeginAmount { get { return _beginAmount; } }

    public ManyProperties(string personName, string decimal? beginAmount) {
       _personName = personName;
       _beginAmount = beginAmount;
    }
}

然后:

var snapshot = whatever.Properties;
var name = snapshot.PersonName;
...
var amount = snapshot.BeginAmount;

现在始终保持一致。另外还有零锁。读取/更新引用也总是原子的 - 所以没有撕裂的值。

重要的是不要这样做:

var name = whatever.Properties.PersonName;
...
var amount = whatever.Properties.BeginAmount;

因为此处不再保证nameamount来自同一个ManyProperties实例:有人可以在两次提取之间交换引用。