簡體   English   中英

確保並發對象調用而不鎖定的最佳方法是什么

[英]What is the best way to ensure concurrent object calls without locking

我有以下對象:

// 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();
  } 
 }

這種方法可能具有一個競爭條件,其中一個線程執行isActive()而另一線程執行load() 盡管它在參考上運行並且對象狀態未更改。

支持此類並發的最佳解決方案是什么? 我想避免方法同步,也避免讀寫鎖定。

也許是AtomicReferencevolatile 還是最好只返回對數據本身的引用而沒有代理方法呢? 因此,根本不需要鎖定,並且所有使用邏輯都在此服務之外嗎?

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

 public MyDataAddOps getData(){
    return data;
  }
 }

您的代碼還沒有朝着產生競爭條件的方向發展。 當前它包含更嚴重的東西,這是一場數據競賽 跨線程發布引用而不會在寫入和將來讀取之間的關系發生之前發生 ,這意味着讀取器可以看到處於部分初始化的不一致狀態的數據對象。 您提出的解決方案對此無濟於事。

一旦你的data字段中volatile ,只有這樣 ,你之間的一個線程首先閱讀的競爭條件data引用,那么另一個線程更新data的參考,那么第一個線程讀取isActive從舊數據。 對於您的邏輯而言,這實際上可能是一個良性案例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM