我的程序中有一个HashMap
,它被多个线程访问,偶尔由一个线程设置。
例如:
Map<String, String> myMap = new HashMap<String, String>();
这是由多个线程访问的。每小时一次,单个线程调用:
myMap = myRefreshedVersionOfTheMap;
所以我的问题是这是否是线程安全的。如果两个 map 始终具有键 "importantKey"
,那么读取线程是否有可能在 "importantKey"
不存在时访问 map ?
编辑:
感谢这些答案,我意识到这个问题实际上与 HashMap
无关。这更多是关于对象引用分配的问题。
最佳答案
这不是线程安全的。即使在发布点之后没有对 map 本身的写入(从执行发布的线程的角度来看),并且引用分配是原子的,新的 Map<>
尚未安全发布。特别是,有在构造过程中对 Map 的写入 - 在构造函数中或之后,取决于您添加这些元素的方式,这些写入可能会或可能不会被其他线程看到,因为尽管它们凭直觉发生在 map 发布到其他线程之前,但根据内存模型,这并不是正式的情况。
要安全发布一个对象,它必须使用某种机制与外界通信,该机制要么在对象构造、引用发布和引用读取之间建立先行关系,要么必须使用少量保证发布安全的更窄的方法:
- 从静态初始化程序初始化对象引用。
- 将对它的引用存储到 final 字段中。
如果您声明 myMap volatile
,您的习语将是安全的.有关安全发布的更多详细信息,请参阅 JCIP (强烈推荐),或 here , 或者在这个longer answer关于类似的主题。
关于java - 设置 HashMap 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17220036/