簡體   English   中英

線程安全地重置對象的引用

[英]Thread-safe resetting of an object's reference

someParameters hashmap每隔20分鍾由一個線程加載一個.csv文件,並由setParameters方法設置

調用getParameters的多個線程經常讀取它:執行一個值到相應值的查找轉換。

代碼是否不安全和/或“錯誤”的方式來實現這一點(特別是在性能方面)? 我知道ConcurrentHashMap,但我試圖對並發性有一個更基本的理解,而不是使用繼承線程安全的類。

我看到的一個潛在風險是,對象引用someParameters可以被重置,而另一個線程正在讀取副本,因此另一個線程可能沒有最新的值(這對我來說無關緊要)。

public class ConfigObject {
    private static HashMap<String, String> someParameters = new HashMap<String, String>();

    public HashMap<String, String> getParameters(){
        return new HashMap<String, String>(someParameters);
        //to some thread which will only ever iterate or get
    }

    public void setParameters(HashMap<String, String> newParameters){
        //could be called by any thread at any time
        someParameters = newParameters;
    }
}

這里有兩個問題

  1. 可見性問題,因為更新后的someParameters可能對其他線程不可見,要修復此標記someParametersvolatile
  2. 其他問題是性能因為在get方法中創建新的HashMap,修復使用Utility方法Collections.unmodifiableMap()這只是包裝原始地圖並禁止put / remove方法。

如果我正確理解您的問題,您需要立即更改/替換許多參數(原子地)。 不幸的是, ConcurrentHashMap不支持原子批量插入/更新。

要實現此目的,您應該使用共享的ReadWriteLock 優勢比較Collections.synchronized...並發讀取,可以同時進行 :如果readLock從某個線程獲取readLock().lock()從另一個線程調用不會阻塞。

ReadWriteLock lock = new ReadWriteLock();

// on write:
lock.writeLock().lock();
try {
   // write/update operation, 
   // e. g. clear map and write new values
} finally {
   lock.writeLock().unlock();
}

// on read:
lock.readLock().lock();
try {
   // read operation
} finally {
   lock.readLock().unlock();
}

暫無
暫無

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

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