问题: 我有一个 ViewModel 基类,它有一个 HashMap 来存储 ViewModel 的属性值。但是,我遇到了一个间歇性错误,即从该集合中读取(在单独的线程上)在添加项目后直接返回 null。
private HashMap<String, Serializable> _propertyValues = new HashMap<String, Serializable>();
示例:我想在向 ViewModel 提供用户 ID 时获取用户信息。
ViewModel 连接到 UserID 的 PropertyChanged。属性更改处理程序创建一个后台线程来提取值。后台线程读取UserID,然后从服务器获取。
我们看到的是,在极少数情况下,后台线程在提供值(线程 1)后直接从属性 HashMap (线程 2)读取 null。
我的想法:我怀疑这是由于 data visibility并且没有线程安全集合。在查看线程安全选项时,我遇到了:
- Hashtable - 似乎社区认为它已过时并不鼓励使用它。
- ConcurrentHashMap - 由于缺乏可靠的同步,我似乎仍然会遇到问题
- Collections.synchronizedMap(map) - 在您使用它的方式上似乎很特别,不确定它是否比 Hashtable 有优势
此时我觉得 Hashtable 是我想要的,但可以使用确认。 :)
用例:
- 大约每分钟一次阅读 100 篇文章。
- 频繁从 UI 线程写入
- 定期从需要准确值的后台线程读取数据。后台线程读取,紧接在 UI 线程写入之后。
谢谢, 特雷
最佳答案
ConcurrentHashMap 就可以了。它有内部同步来防止这类问题。它还具有您可能会觉得有用的其他方法,例如 putIfAbsent
。
它相对于 Collections.synchronizedMap
的主要缺点是占用更大的内存。
关于java - 哈希表、ConcurrentHashMap 和数据可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21342160/