java - 哈希表、ConcurrentHashMap 和数据可见性

标签 java multithreading concurrency hashmap

问题: 我有一个 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并且没有线程安全集合。在查看线程安全选项时,我遇到了:

  1. Hashtable - 似乎社区认为它已过时并不鼓励使用它。
  2. ConcurrentHashMap - 由于缺乏可靠的同步,我似乎仍然会遇到问题
  3. Collections.synchronizedMap(map) - 在您使用它的方式上似乎很特别,不确定它是否比 Hashtable 有优势

此时我觉得 Hashtable 是我想要的,但可以使用确认。 :)

用例:

  1. 大约每分钟一次阅读 100 篇文章。
  2. 频繁从 UI 线程写入
  3. 定期从需要准确值的后台线程读取数据。后台线程读取,紧接在 UI 线程写入之后。

谢谢, 特雷

最佳答案

ConcurrentHashMap 就可以了。它有内部同步来防止这类问题。它还具有您可能会觉得有用的其他方法,例如 putIfAbsent

它相对于 Collections.synchronizedMap 的主要缺点是占用更大的内存。

关于java - 哈希表、ConcurrentHashMap 和数据可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21342160/

相关文章:

用于监控音频的java生产者消费者线程

grails - 如果超时,是否有任何方法可以获取 PromiseList 的结果

java - LinkedBlockingQueue 和 PriorityBlockingQueue 有什么区别?

java - Spring 批处理中的验证步骤

java - Elasticsearch Java API 2.3 问题

c++ - 高效地分配许多短命的小对象

java - 无法创建新的 native 线程

java - ListSelectionModel - getMinSelectionIndex() 错误地返回 -1

java - Spring Boot 将事务(和数据库连接)传播到 @Async 方法

c# - 为什么 ConcurrentBag<T> 在 .Net (4.0) 中这么慢?我做错了吗?