【问题标题】:Read-only access to cached data from multiple Java threads对来自多个 Java 线程的缓存数据进行只读访问
【发布时间】:2013-10-28 18:46:01
【问题描述】:

在一个 8 核 64G EC2 实例上运行,我有一个 Java 应用程序,它的主线程在一个 Hashmap 中缓存了几十 GB 的数据。缓存完成后,会产生 16 个工作线程(作为 Thread 的子类)。他们收到对 Hashmap 的引用。工作线程只是读取缓存的数据,他们从不修改它。我希望所有工作线程都看到相同的缓存数据。然而事实并非如此。原来Hashmap中的数据有漏洞。对于某些键,工作线程看不到任何值。这总是发生在相同的键上!当我只产生 1 个工作线程时,一切都很好。有什么想法吗?

【问题讨论】:

  • 你是说 hashmap 仅在创建访问它的线程之前被修改?
  • 你的几十G的地图是怎么生成的?是单线程,是从磁盘读取的吗?
  • 是的,hashmap 仅在创建工作线程之前被修改。哈希图是在单个(主)线程中从磁盘创建的。更准确地说,hashmap 的值是对象,缓存的数据存储在 THashMap 对这些对象的私有中。

标签: java multithreading


【解决方案1】:

在线程中传递引用时可能会出错。这是一个清单:

  • 在创建工作线程之前,HashMap 是否已经完全初始化?
  • 如果在完全写入哈希图之前创建了线程,您是否使用同步块来传递对哈希图的引用?
  • 或者,您可以使用 ConcurrentHashMap 吗?这已针对安全地从多个线程读取(和写入)进行了优化。
  • 要在工作线程启动后更改哈希映射,请确保在同步块中更改哈希映射,并且工作线程在与第一个同步对象相同的对象上的同步块中读取映射(这是低效的,并且根据您的使用情况,有更好的方法。

要全面了解线程安全,您应该阅读 Java 内存模型或 Java 并发实践这本书。

【讨论】:

  • 是的,在创建工作线程之前,HashMap 已经完全初始化。我还尝试将 HashMap 声明为 volatile 以确保每个 CPU 内核都能获取全部数据,但无济于事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-01
  • 2023-02-23
  • 2014-12-27
相关资源
最近更新 更多