在没有锁定的情况下确保并发对象调用的最佳方法是什么

Jul*_*ias 2 java concurrency multithreading

我有以下对象:

// this class is immutable, acts like container for several properties.
public class MyDataAddOps{
    private final boolean isActive;
    private final Map<String,Object> additionalProps;

    public MyDataAddOps(boolean isActive, Map<String,Object> additionalProps){
       this.isActive = isActive;
       this.additionalProps = additionalProps;
    }

   public boolean isActive(){return isActive;}
   public Map<String,Object> getAdditionalProps(){ return additionalProps;}
}

// this class acts as "spring" bean that calls load on construction,
//  and then another scheduler bean calls the load per some cron expression (once a minute for example) 
public class MyDataAddOpsService{
   private MyDataAddOps data;

   // this method will be executed periodically outside
   // via some spring quartz for example
   // the quartz is not re-entrant  
   public void load(){
      // opens some defined file and returns content string 
      String fileData = getFileContent(); 
      boolean isActive = getIsActive(fileData);
      Map<String, Object> props = getProps(fileData);
      data = new MyDataAddOps(isActive, props);
   }

  // This method is executed by many workers threads inside the application
  public boolean isActive(){
     return data.isActive();
  }

  public final Map<String, Object> getProps(){
      return data.getAdditionalProps();
  } 
 }
Run Code Online (Sandbox Code Playgroud)

这种方法可能具有竞争条件,其中一个线程执行isActive()而另一个执行load().虽然它在引用上运行但对象状态没有改变.

支持这种并发的最佳解决方案是什么?我想避免同步方法,还有读写锁.

也许AtomicReference还是volatile?或者,如果没有代理方法,只返回对数据本身的引用会更好?所以根本不需要锁定,所有使用逻辑都在这个服务之外?

 public class MyDataAddOpsService{
   private MyDataAddOps data;
   public void load(){
     ....
     data = new MyDataAddOps(isActive, props);
   }

 public MyDataAddOps getData(){
    return data;
  }
 }
Run Code Online (Sandbox Code Playgroud)

Mar*_*nik 5

你的代码还没有朝着竞争状态发展; 目前它包含更严重的东西,这是一场数据竞赛.在写入和将来读取之间的关系之前,跨线程发布引用而不会引发发生意味着读取器可以看到处于部分初始化,不一致状态的数据对象.您提出的解决方案对此没有帮助.

一旦你创建了data字段volatile,只有这样你才能在一个线程首先读取data引用,然后是另一个更新data引用的线程,然后是isActive从旧数据读取的第一个线程之间有竞争条件.这实际上可能是您逻辑的良性情况.