我有一张地图(让我们称之为原始地图),该地图最初为空。在服务部署期间以及之后的每个小时,我需要刷新此映射或基本上重新放置它。
我是这样做的。在刷新时,我创建了一个新的地图,并将该新地图的不可修改的Map视图返回到我的原始地图,现在当这个重新分配发生时,原始地图的参考被更改,它是否会影响当前访问该地图的任何其他线程原图?需要注意的是,在服务部署期间,原始地图以类似的方式分配了一个值,基本上使用相同的刷新策略。
private static Map<String, PricingPriceList> plInfoByName;
TransactionData.plInfoByName = plInfo.get(0);
这里plInfoByName是我的原始地图,plInfo包含一个不可修改的地图列表。以下是填充plInfo列表的方法
Map<String, PricingPriceList> plInfoByName = new HashMap<String, PricingPriceList>();
Map<String, PricingPriceList> plInfoById = new HashMap<String, PricingPriceList>();
try {
stmt = dbConn.createStatement();
stmt.setFetchSize(10000);
rs = stmt.executeQuery(query);
PricingPriceList plDetails = null;
while (rs.next()) {
plDetails = new PricingPriceList();
//populate plDetails attributes
plInfoByName.put(rs.getString(0), plDetails);
plInfoById.put(rs.getString(1), plDetails);
}
} catch (Exception e) {
LOGGER.ERROR("Error executing refreshPlInfo. Affected in-memory objects: plInfoByName, plInfoById.", e);
} finally {
try {
if (stmt != null && !stmt.isClosed()) {
stmt.close();
}
if (rs != null && !rs.isClosed()) {
rs.close();
}
} catch (SQLException e) {
LOGGER.ERROR("refreshPlInfo failed to close SQL statement or resultset.", e);
}
}
// Return unmodifiable version
List<Map<String, PricingPriceList>> plInfo = new ArrayList<Map<String, PricingPriceList>>();
plInfo.add(Collections.unmodifiableMap(plInfoByName));
plInfo.add(Collections.unmodifiableMap(plInfoById));
return plInfo;
所以当我这样做时,它会影响任何读取TransactionData.plInfoByName的线程吗?或者它是否是线程安全的,因为它是存储在其中的unModifiableMap。
TransactionData.plInfoByName = plInfo.get(0);
答案 0 :(得分:2)
unmodifiableMap
本身并不是线程安全的,它只是阻止用户更改它。在当前线程正在读取时,另一个可以访问底层映射的线程仍然可以更改它。
但是,如果您只是更改对地图的引用,则不应该影响当前正在访问&#34; old&#34;地图。假设(我必须检查一下)获取对象的引用是一个或多或少的原子操作(参见这里:What operations in Java are considered atomic?),任何引用了&#34; old& #34; map应该保留它,直到它再次检索引用。
示例:
假设以下操作: