【发布时间】: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#put和Cache#get不是synchronized您可能会出现竞争条件。 -
put 是从同步的包装类方法中调用的,该方法从 db 获取数据并准备 cityMap
标签: java multithreading singleton