【问题标题】:Singleton returning empty Object单例返回空对象
【发布时间】:2019-04-03 05:56:57
【问题描述】:

我们的项目中有一个缓存实现,为此我们使用了单例设计模式。 Class Cache 是一个单例类,里面有一个HashMap<String,HashMap> m。有时当我们从 Hashmap m 获取数据时。返回的内部 HashMap 为空。这是随机发生的,我们不知道为什么会发生。我们已经确保在我们的代码中没有在 map 上调用 remove 语句,并且不存在删除这些数据的代码。

这方面的任何线索都会非常有帮助。 提前致谢。

缓存类:-

public Class Cache
{
    public static Cache c;
    private HashMap<String,HashMap> m ;
    private Cache()
    {
         m = new HashMap<String,HashMap>();
    }
    public static synchronized Cache getInstance()
    {
        if(c == null) { c = new Cache(); }
        return c;
    }
    public void put(String id,HashMap value)
    {    m.put(id,value);     }
    public HashMap get(String id)
    {    return m.get(id);    }
}

价值代码:-

Cache c = Cache.getInstance();
c.put("CITY_CACHE",cityMap);// cityMap is a non empty map having city data

获取值的代码:-

Cache c = Cache.getInstance();
HashMap cityMap = c.get("CITY_CACHE");
//city Map here becomes empty sometimes

这种情况在生产中随机发生,我们无法在非生产环境中复制。我怀疑它是因为 GC,但没有证据证明这一点。

【问题讨论】:

  • 缺少(可能是必要的)同步? (您使用的是HashMap)。
  • 是的。没有看到任何代码,或者对您的项目一无所知,这将非常容易回答。猜猜看:你的内部 Hashmap 是空的。如果您想知道原因:重新检查您的代码和操作流程
  • 更新了帖子以便更好地理解,谢谢
  • 给出的代码不够用。您需要弄清楚其他代码在哪里也调用c.put("CITY_CACHE",cityMap) 并覆盖该条目。此外,如果 Cache#putCache#get 不是 synchronized 您可能会出现竞争条件。
  • put 是从同步的包装类方法中调用的,该方法从 db 获取数据并准备 cityMap

标签: java multithreading singleton


【解决方案1】:

当您同步获取Cache 实例时,您不会保护内部映射的操作。您应该同步这些操作或使用线程安全的映射实现,例如ConcurrentHashMap

【讨论】:

  • 感谢您的建议。我们也试过了。结果是一样的。
  • @NishantModi 你找到解决方案了吗?
  • 不,还没有,我们只是添加了一个解决方法,当它为空时重新加载它。
【解决方案2】:

由于我没有你项目的完整背景,我可以建议你一些调试步骤。我不认为问题是由于同步造成的。在您获得相同数据之前,您的代码的某些部分可能会删除数据(这种情况可能会在同步或不同步的情况下发生)。

当您使用钥匙找不到数据时,在日志中打印地图数据。检查数据是否存在于不在日志中?显然我们不能怀疑java中Hashmap的get方法:)

是的,GC 也可能是原因。

【讨论】:

  • 您能否在 GC 部分提供更多帮助
  • @NishantModi 您可以使用以下参数运行您的 java 应用程序并捕获 GC 日志并检查日志中 GC 的停止时间。当地图中没有数据时,还要记录详细信息。并比较两个日志的时间。 -XX:+PrintGCDetails -Xloggc: 了解GC日志。 plumbr.io/blog/garbage-collection/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
  • 2014-09-29
  • 2015-02-11
  • 2020-12-21
  • 2019-04-08
相关资源
最近更新 更多