多线程延迟初始化

时间:2012-01-29 15:50:41

标签: java multithreading lazy-evaluation

我对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和Peter,

我认为以下内容也将解决线程安全问题:

public Object getObjectA()
{
  Object obj = new Object()
  obj.setProperty("prp1");  
  return obj;                                                                                   
}

6 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

是的,它会产生问题(尝试代码看看会出现什么样的问题,但数据会丢失)。 最简单的解决方案是使用synchronized块。

答案 2 :(得分:0)

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

是的,此代码可能会遇到竞争条件,其中obj的值可能取决于线程执行的顺序(即多个线程调用getObj ..()的顺序)。

您需要synchronize访问obj变量。

答案 3 :(得分:0)

我认为getObjectA()getObjectB()应该声明为私有,然后你应该在returnObject()方法中使用synchronized块,所以像这样:

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

} 

显然 true 条件必须替换为某些条件......

答案 4 :(得分:0)

我建议将代码更改为 NOT 将“obj”保存为数据成员,因为它需要同时访问。

有几种解决方案:

  1. 在函数
  2. 中本地创建对象
  3. 使用可以“包装”'obj'数据成员的ThreadLocal对象
  4. 为本地对象的每次调用创建一次对象和用户clone()并进行编辑。

答案 5 :(得分: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