2012-01-29 122 views
0

我有一个关于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;                     
} 
+0

@skaffman我认为这是一个实际的,有意义的条件的占位符 – Bohemian 2012-01-29 16:06:53

+0

@Bohemian你是正确的 – 2012-01-29 16:11:48

+0

当你使用一个字段或变量时,通常最好将范围限制在仅仅需要它的地方。在这种情况下,它实际上可以解决您的问题。 – 2012-01-29 20:32:40

回答

0

是。

如果两个线程在returnObject()同时调用不同的代码路径,它可以在getObjectA()运行两个语句之间getObjectB(),最终调用对象B obj.setProperty("prp1");

+0

Ahh thanx SLaks。 () – 2012-01-29 16:01:20

0

是的,它会产生问题(尝试代码来查看哪些类型的问题,但数据会丢失)。 最简单的解决方案是使用​​块。

+0

嗨,彼得,如果我去公共对象getObjectA() { Object obj = new Object() obj.setProperty(“prp1”);返回obj; } – 2012-01-29 16:06:24

+0

这应该没问题。 – 2012-01-29 16:53:25

0

提供,if(true)没有硬编码,因为这将修复始终调用getObjA()的执行路径!

是的,这段代码可能会遇到竞争状态,obj的值可能取决于线程执行的顺序(即多线程调用getObj ..()的顺序)。你需要synchronize访问obj变量。

0

我认为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"); 
} 

} 

显然真正条件必须被一些条件所取代...

0

我建议更改为代码为不是保留'obj'作为数据成员,因为它需要同时访问。

有几种解决方案:

  1. 功能内本地创建对象
  2. 使用ThreadLocal的对象,可以“包装”的“OBJ”数据成员
  3. 创建对象一旦和用户clone()用于每个本地调用本地对象并对其进行编辑。
0

是的,但是这是非常简单的修复,因为要更换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