我正在尋找一種方法來次相同的密鑰插入嘗試次數的軌道保持到Map
在多線程environemnt使得Map
可同時由多個線程讀取和更新。如果保持跟蹤重複密鑰插入嘗試不容易實現,則替代解決方案是在重複密鑰插入嘗試的第一個符號處終止應用程序。保持重複插入的軌道在一個Map(多線程環境)
以下用戶定義的單例Spring bean顯示了我的應用程序使用的全局緩存,該緩存使用多個分區的彈簧批處理作業(每個要加載的DataType
需要一個作業)加載。 addResultForDataType
方法可以被多個線程同時調用。
public class JobResults {
private Map<DataType, Map<String, Object>> results;
public JobResults() {
results = new ConcurrentHashMap<DataType, Map<String, Object>>();
}
public void addResultForDataType(DataType dataType, String uniqueId, Object result) {
Map<String, Object> dataTypeMap = results.get(dataType);
if (dataTypeMap == null) {
synchronized (dataType) {
dataTypeMap = results.get(dataType);
if (dataTypeMap == null) {
dataTypeMap = new ConcurrentHashMap<String, Object>();
results.put(dataType, dataTypeMap);
}
}
}
dataTypeMap.put(uniqueId, result);
}
public Map<String, Object> getResultForDataType(DataType dataType) {
return results.get(dataType);
}
}
這裏:
DataType
可以爲其中的數據被加載從 表名或文件名被認爲。每個DataType指示一個表或文件。uniqueId
表示表或文件中每個記錄的主鍵。result
是表示整行的對象。- 上述方法每個記錄調用一次。在任何給定時間,多個線程可以插入相同的
DataType
或不同的DataType
的記錄。
我想創造另一個地圖,以保持重複插入的軌跡:
public class JobResults {
private Map<DataType, Map<String, Object>> results;
private Map<DataType, ConcurrentHashMap<String, Integer>> duplicates;
public JobResults() {
results = new ConcurrentHashMap<DataType, Map<String, Object>>();
duplicates = new ConcurrentHashMap<DataType, ConcurrentHashMap<String, Integer>>();
}
public void addResultForDataType(DataType dataType, String uniqueId, Object result) {
Map<String, Object> dataTypeMap = results.get(dataType);
ConcurrentHashMap<String,Integer> duplicateCount = duplicates.get(dataType);
if (dataTypeMap == null) {
synchronized (dataType) {
dataTypeMap = results.get(dataType);
if (dataTypeMap == null) {
dataTypeMap = new ConcurrentHashMap<String, Object>();
duplicateCount = new ConcurrentHashMap<String, Integer>();
results.put(dataType, dataTypeMap);
duplicates.put(dataType, duplicateCount);
}
}
}
duplicateCount.putIfAbsent(uniqueId, 0);
duplicateCount.put(uniqueId, duplicateCount.get(uniqueId)+1);//keep track of duplicate rows
dataTypeMap.put(uniqueId, result);
}
public Map<String, Object> getResultForDataType(DataType dataType) {
return results.get(dataType);
}
}
我意識到statemet duplicateCount.put(uniqueId, duplicateCount.get(uniqueId)+1);
沒有隱含線程安全的。爲了使其線程安全,我將需要使用同步,這會減慢我的插入。如何在不影響應用程序性能的情況下跟蹤重複插入。如果保留重複插入的軌跡並不容易,那麼只要在嘗試覆蓋地圖中現有條目的第一個符號處引發異常就可以了。我知道Map
不允許重複的鍵。我想要的是一種跟蹤任何此類嘗試的方法,並暫停應用程序,而不是覆蓋Map
中的條目。
您是否在尋找避免對外部或內部'Map'的重複? – Actorclavilis
@Actorclavilis只是外面的地圖。 (請參閱我的解決方案嘗試)。 – Ping