单例返回空对象

时间:2019-04-03 05:56:57

标签: java multithreading singleton

我们的项目中有一个缓存实现,为此我们使用了单例设计模式。类缓存是一个单例类,其中包含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,但没有证据证明它。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

当您用键找不到任何数据时,在日志中打印地图数据。检查数据是否不在日志中?显然,我们不能怀疑Java中Hashmap的get方法:)

是的,GC也可能是原因。