我听说过在非线程安全代码中由于不正确的对象构造而发生这种情况,但我真的不了解这个概念,即使在Goetz的书中读到了。我想巩固我对这个代码气味的理解,因为我可能正在做它,甚至没有意识到它。请在您的解释中提供代码以使其具有说服力,谢谢。
发布于 2009-10-19 12:39:24
非常简单的例子:
public class Test
{
private static Test lastCreatedInstance;
public Test()
{
lastCreatedInstance = this;
}
}
发布于 2009-10-19 12:42:01
这就是双重检查锁定不起作用的原因。朴素的代码
if(obj == null)
{
synchronized(something)
{
if (obj == null) obj = BuildObject(...);
}
}
// do something with obj
是不安全的,因为对局部变量的赋值可能发生在构造(构造函数或工厂方法)的其余部分之前。因此,当线程2进入相同的块,检测到非空的obj
,然后继续对不完整的对象进行操作时,线程1可以处于BuildObject
步骤中(线程1已经在中间调用中被调度出去)。
发布于 2009-10-19 12:45:04
public class MyClass{
String name;
public MyClass(String s)
{
if(s==null)
{
throw new IllegalArgumentException();
}
OtherClass.method(this);
name= s;
}
public getName(){ return name; }
}
在上面的代码中,向OtherClass.method()
传递了MyClass
的一个实例,该实例当时未完全构造,即尚未履行name
属性为非空的约定。
https://stackoverflow.com/questions/1588420
复制相似问题