多线程懒惰初始化
我有一个关于java多线程的问题。多线程懒惰初始化
我有一个类可以访问多个线程。
Class A
{
private Object obj;
public Object returnObject()
{
if(condition)
return getObjectA();
else
return getObjectB();
}
public Object getObjectA()
{
obj = new Object()
obj.setProperty("prp1");
}
public Object getObjectB()
{
obj = new Object()
obj.setProperty("prp2");
}
}
当有多个线程访问getObj ..()。它是否会造成“obj”状态的问题?会有不希望的结果吗?
感谢SLaks和彼得,
我认为有以下也将解决线程安全问题:
public Object getObjectA()
{
Object obj = new Object()
obj.setProperty("prp1");
return obj;
}
是。
如果两个线程在returnObject()
同时调用不同的代码路径,它可以在getObjectA()
运行两个语句之间getObjectB()
,最终调用对象B obj.setProperty("prp1");
。
Ahh thanx SLaks。 () – 2012-01-29 16:01:20
是的,它会产生问题(尝试代码来查看哪些类型的问题,但数据会丢失)。 最简单的解决方案是使用块。
嗨,彼得,如果我去公共对象getObjectA() { Object obj = new Object() obj.setProperty(“prp1”);返回obj; } – 2012-01-29 16:06:24
这应该没问题。 – 2012-01-29 16:53:25
提供,if(true)
没有硬编码,因为这将修复始终调用getObjA()的执行路径!
是的,这段代码可能会遇到竞争状态,obj
的值可能取决于线程执行的顺序(即多线程调用getObj ..()的顺序)。你需要synchronize
访问obj变量。
我认为getObjectA()
和getObjectB()
应该被声明为私有的,当时你应该使用returnObject()
方法内同步块,所以这样的事情:
class A
{
private Object obj;
public Object returnObject()
{
Object result;
synchronized (A.class) {
result = (true) ? getObjectA() : getObjectB();
}
return result;
}
private Object getObjectA()
{
obj = new Object()
obj.setProperty("prp1");
}
private Object getObjectB()
{
obj = new Object()
obj.setProperty("prp2");
}
}
显然真正条件必须被一些条件所取代...
我建议更改为代码为不是保留'obj
'作为数据成员,因为它需要同时访问。
有几种解决方案:
- 功能内本地创建对象
- 使用ThreadLocal的对象,可以“包装”的“OBJ”数据成员
- 创建对象一旦和用户
clone()
用于每个本地调用本地对象并对其进行编辑。
是的,但是这是非常简单的修复,因为要更换obj
每一个电话,你显然不关心它,所以尽量让现场obj
只是一个局部变量,就像这样:
Class A {
public Object returnObject() {
if (true)
return getObjectA();
return getObjectB();
}
public Object getObjectA() {
Object obj = new Object()
obj.setProperty("prp1");
return obj;
}
public Object getObjectB() {
Object obj = new Object()
obj.setProperty("prp2");
return obj;
}
}
如果这对你有用,请考虑制作这些方法static
。
@skaffman我认为这是一个实际的,有意义的条件的占位符 – Bohemian 2012-01-29 16:06:53
@Bohemian你是正确的 – 2012-01-29 16:11:48
当你使用一个字段或变量时,通常最好将范围限制在仅仅需要它的地方。在这种情况下,它实际上可以解决您的问题。 – 2012-01-29 20:32:40