多线程延迟初始化



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

是。

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

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

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

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

您需要synchronize对obj变量的访问权限。

是的,但这很容易修复,因为每次调用都要替换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

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

有几种解决方案:

  1. 在函数内部本地创建对象
  2. 使用可以"包装"obj"数据成员的ThreadLocal对象
  3. 创建一次Object,每次本地调用本地Object时使用clone()并对其进行编辑

我认为getObjectA()getObjectB()应该被声明为private,然后你应该在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");
}
} 

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

最新更新