读书人

Map的HashCode干缓存key值引发的重大b

发布时间: 2012-10-07 17:28:51 作者: rapoo

Map的HashCode做缓存key值引发的重大bug

现象:

计费和账户的交互通过Map来交互,基本数据格式如下{"pp900_88",20,"pp900_61",2……}

在不同的取值情况下,较多数据返回了相同的价格结果,导致计算价格错误。

?

应用场景:

产品计算价格时,使用cache缓存了价格结果数据,cache的key值是传入map的hashCode,本意是要实现完全相同的Map传入值从缓存取数据,减少数据库的访问。

?

?

原因分析:

?

一。通过如下代码模拟线上应用:

 public final int hashCode() {            return (key==null   ? 0 : key.hashCode()) ^                   (value==null ? 0 : value.hashCode());        }

?

以? m1.put("pp900_88", 1);? m1.put("pp900_61", 1);和

???? m1.put("pp900_88", 2);? m1.put("pp900_61", 2);为例子:得到的key-Value的hashCode值如下

?

key?????????????????? key的hashCode???value的hashCode? Map的hashCode(key^value)

??pp900_88??????? -79859962???????????? 1???????????????????? ? -79859961

??pp900_61????????-79860031???????????? 1?????????????????????? -79860032??pp900_88????????-79859962???????????? 2?????????????????????? -79859964??pp900_61????????-79860031 ??????????? 2???????????????????????-79860029?显然根据Map的hash值算法, Map的hashCode相加:第一行+第二行=第三行+第四行,这样产生重复数据也在所难免了,因为hashCode本来就不保证不同的输入值不会产生相同的结果。JSL的约束是对于相同的对象,必须产生相同的hashCode。结论和改进措施:1.不建议对结果进行缓存,结果缓存会带来很多问题,比如哪些数据变更需要刷新哪些缓存,缓存最好对原始纪录值进行缓存。2.key值不采用hashCode算法,直接改为使用各个key-value的String拼接字符串。?

?

读书人网 >软件架构设计

热点推荐