我们的项目中有一个缓存实现,为此我们使用了单例设计模式。类缓存是一个单例类,其中包含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,但没有证据证明它。
答案 0 :(得分:1)
在同步获取Cache
实例的同时,您没有保护内部映射的操作。您应该同步这些操作或使用线程安全的映射实现,例如ConcurrentHashMap
。
答案 1 :(得分:0)
由于我没有您的项目的完整背景,因此我可以建议您一些调试步骤。我认为问题不在于同步。在获取相同数据之前,代码的某些部分可能会删除数据(这种情况可能发生在有或没有同步的情况下)。
当您用键找不到任何数据时,在日志中打印地图数据。检查数据是否不在日志中?显然,我们不能怀疑Java中Hashmap的get方法:)
是的,GC也可能是原因。