gpt4 book ai didi

java - 更新 unmodifiedMap 线程的引用是否安全

转载 作者:行者123 更新时间:2023-12-02 03:50:13 25 4
gpt4 key购买 nike

我有一张 map (我们称之为原始 map ),它最初为空。在服务部署期间以及此后的每个小时,我都需要刷新此 map 或基本上重新评估它。

这是我的做法。在刷新中,我创建一个新 map ,并将该新 map 的不可修改 map View 返回到我的原始 map ,现在,当发生重新分配时,原始 map 的引用发生更改,它会影响当前访问该 map 的任何其他线程吗?原始 map ?需要注意的是,在服务部署过程中,原始 map 的赋值方式类似,刷新策略基本相同。

        private static Map<String, PricingPriceList> plInfoByName;
TransactionData.plInfoByName = plInfo.get(0);

这里 plInfoByName 是我的原始 map ,plInfo 包含不可修改 map 的列表。以下是 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 的线程吗?或者它是线程安全的,因为它是存储在其中的不可修改的映射。

    TransactionData.plInfoByName = plInfo.get(0);

最佳答案

unmodifyingMap 本身并不是线程安全的,它只是阻止用户更改它。当当前线程正在读取时,有权访问底层映射的另一个线程仍然可以更改它。

但是,如果您只是更改对 map 的引用,则不会影响当前正在访问“旧” map 的任何线程。假设(我必须检查)获取对对象的引用或多或少是一个原子操作(请参见此处: What operations in Java are considered atomic? ),任何获取对“旧”映射的引用的线程都应保留它,直到它再次检索引用。

示例:

假设进行以下操作:

  • 变量“map”包含对 map A 的引用
  • T1 通过“map”检索映射 A 并将该引用存储在某个局部变量中,我们称之为“t1Map”
  • T2 现在将“ map ”更改为引用 map B
  • T1 通过“t1Map”访问 map ,该 map 仍引用 A
  • T1 再次通过“map”检索 map A,现在将获取对 B 的引用

关于java - 更新 unmodifiedMap 线程的引用是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35944839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com