如何在踏板之间强制同步字段值一次?

时间:2016-06-02 09:41:42

标签: c# multithreading

代码示例

    public class MyClass{
        private MyObject myObject;        
        private Object lockObject = new Object();        
        MyObjectFactory factory;

        public MyClass(MyObjectFactory factory){
            this.factory = factory; 
        }

        public MyObject GetObject()
        {
           if (myObject == null){
               lock(lockObject){
                  myObject = factory.Create();
                  //need forcibly sync myObject value beetween all threads here
               }
           }
           return myObject;
        }
    }

MyClass 的实例共享beetwen几个线程。我知道我可以使用 volatile myObject ,它会在写入时同步字段值,但我也会慢速读取。是否可以将 myObject 值仅一次同步到没有 volatile 的锁定部分?

2 个答案:

答案 0 :(得分:2)

您需要稍微更改代码,以便它实现双重检查模式:

public MyObject GetObject()
{
    if (myObject == null)
    {
       lock(lockObject)
       {
          if (myObject == null)
          {
              myObject = factory.Create();
          }
       }
    }
    return myObject;
}

如果您的代码只能在x86 / x64处理器上运行,那么您不需要volatile关键字,因为CPU内存模型足够强大,可以确保其他线程看到对{{}的更改1}}在myObject语句中,或者在获取锁定后肯定在第二个if语句中。

或者,您可以使用if类向您隐藏此内容:

LazyInitializer

在这里,你只需要在创建对象时对布尔值进行易失性读取。请注意,如果您尚未创建锁定对象,该方法将为您分配锁定对象。

答案 1 :(得分:0)

在这种情况下,您必须使用委托。该线程将使用委托访问主线程中的方法以将数据传递给它,并允许它立即采取行动,假设您在创建bew线程时没有使用连接。