我有一张地图(我们称之为原始地图),它最初为空。在部署服务期间以及之后的每隔一小时,我需要刷新此映射或基本上对其进行处理。更新不可修改地图线程的引用安全
这是我该怎么做。在刷新过程中,我创建了一个新的地图,并将该新地图的一个不可修改的地图视图返回到了我的原始地图,而现在这个重新分配发生了,那就是原始地图的引用发生了变化,它是否会影响当前访问原始地图?需要注意的是,在服务部署期间,原始地图以类似的方式被赋值,基本上使用相同的刷新策略。
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);
所以我们只是需要确认在java中这个任务操作是否是原子或没有?事实上,这是我主要关心的是,重新分配会影响任何当前的线程。 –
@ArnavSengupta看看我链接的线程。它说分配是原子的 - 我必须在JLS中查找相应的部分。 – Thomas
只需添加,线程不会将其存储在局部变量中,它们全都从此公共映射中读取,TransactionData.plInfoByName。 –