代码示例
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 的锁定部分?
答案 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线程时没有使用连接。