我有一个HashMap
在我的程序中,它由多个线程访问,并且偶尔由单个线程设置。
例如:
Map<String, String> myMap = new HashMap<String, String>();
这是由多个线程访问的。一个线程每小时调用一次:
myMap = myRefreshedVersionOfTheMap;
所以我的问题是这是否是线程安全的。如果两张地图总是有钥匙"importantKey"
,读取线程是否有可能在某个时间访问地图"importantKey"
不存在?
Edit:
感谢答案,我意识到这个问题实际上与HashMap
。这更多是一个关于对象引用分配的问题。
这不是线程安全的。即使在发布点之后没有对映射本身进行写入(从执行发布的线程的角度来看),并且引用分配是原子的,新的Map<>
一直没有安全发布。特别是,有are在构造期间写入 Map - 无论是在构造函数中还是之后,具体取决于您添加这些元素的方式,并且这些写入可能会或可能不会被其他线程看到,因为即使它们直观地发生在映射发布到其他线程之前,根据内存模型,这并不是正式的情况。
为了安全地发布一个对象,它必须使用某种机制与外界通信,该机制要么在对象构造、引用发布和引用读取之间建立发生之前的关系,要么必须使用一些更窄的方法保证发布安全:
- 从静态初始值设定项初始化对象引用。
- 将对它的引用存储到最终字段中。
如果您声明了 myMap,您的习惯用法将是安全的volatile
。有关安全发布的更多详细信息,请参阅JCIP http://jcip.net.s3-website-us-east-1.amazonaws.com/(强烈推荐),或者here https://stackoverflow.com/questions/801993/java-multi-threading-safe-publication,或者在这个更长的答案 https://stackoverflow.com/a/41990379/149138关于类似的话题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)