使用缓存cache 的大坑

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

使用缓存cache 的大坑 - Mr_Smile2014的博客
- 博客频道 - CSDN.NET

Mr_Smile2014的博客

【活动】2017 CSDN博客专栏评选

&nbsp

【5月书讯】流畅的Python,终于等到你!
   &nbsp

CSDN日报20170517 ——《怎样和虐死人的老项目谈恋爱》

使用缓存cache 的大坑

标签:
DefaultKeyGeneratorgenerate缓存cache

2017-05-18 11:48
228人阅读
评论(0)
收藏
举报

本文章已收录于:

.embody{
padding:10px 10px 10px;
margin:0 -20px;
border-bottom:solid 1px #ededed;
}
.embody_b{
margin:0 ;
padding:10px 0;
}
.embody .embody_t,.embody .embody_c{
display: inline-block;
margin-right:10px;
}
.embody_t{
font-size: 12px;
color:#999;
}
.embody_c{
font-size: 12px;
}
.embody_c img,.embody_c em{
display: inline-block;
vertical-align: middle;
}
.embody_c img{
width:30px;
height:30px;
}
.embody_c em{
margin: 0 20px 0 10px;
color:#333;
font-style: normal;
}


分类:

问题集锦(27)

作者同类文章X

JAVA(44)

作者同类文章X

版权声明:本文为博主原创文章,未经博主允许不得转载。

这段时间发现系统取数据过程中,偶尔出现取数据错乱的问题,按逻辑应该取出A数据,结果取出了B数据。仔细检查了代码,

发现代码逻辑没有问题,瞬间就蒙了,是哪里出现问题了呢。仔细想了一下,以前都没出现问题,自从加了缓存之后就偶尔出现了问

题,那肯定问题是缓存有问题。

仔细研究了缓存的源码,原来问题出现在DefaultKeyGenerator生成key上面。代码如下:

 public class DefaultKeyGenerator implements KeyGenerator {

	public static final int NO_PARAM_KEY = 0;
	public static final int NULL_PARAM_KEY = 53;

	public Object generate(Object target, Method method, Object... params) {
		if (params.length == 1) {
			return (params[0] == null ? NULL_PARAM_KEY : params[0]);
		}
		if (params.length == 0) {
			return NO_PARAM_KEY;
		}
		int hashCode = 17;
		for (Object object : params) {
			hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : object.hashCode());
		}
		return Integer.valueOf(hashCode);
	}

}

从源码中我们发现,当参数:params有一个或0的时候,直接返回NULL_PARAM_KEY或者参数params[0],假如params参数大于1

的时候返回的是各个参数的hash值相加的值+31*17。这样就出现问题了,虽然取A数据与取B数据的各个参数的值不一样,但是有可能它们

参数的hashcode值是一样的,那么就可能出现取A数据把B数据取出来了。(cache中就像map一样,有key和value,根据key来取value值)。

比如下面代码,虽然参数值不一样但是key是相同的。

public static void main(String argv[])
	{
		DefaultKeyGenerator g  = new DefaultKeyGenerator();
		Integer param0 = 1000000759;
		String param1 = "11";
		System.out.println(" param0="+param0+", param1="+param1+"  generate key: "+g.generate(null,null,param0,param1));
		Integer param01 = 1000000757;
		String param11 = "31";
		System.out.println("param01="+param01+",param11="+param11+"  generate key: "+g.generate(null,null,param01,param11));
	}

运行结果如下:

---------------------------------------------------------------------------版权声明------------------------------------------------------------------------------------------

版权声明:本文为博主原创文章,未经博主允许不得转载。博客地址:http://blog.csdn.net/mr_smile2014

时间: 2024-10-21 13:21:16

使用缓存cache 的大坑的相关文章

[.net 面向对象程序设计进阶] (14) 缓存(Cache) (一) 认识缓存技术

[.net 面向对象程序设计进阶] (14) 缓存(Cache)(一) 认识缓存技术 本节导读: 缓存(Cache)是一种用空间换时间的技术,在.NET程序设计中合理利用,可以极大的提高程序的运行效率. 本节将介绍如何利用缓存写出高效率的代码. 1. 什么是缓存(Cache)? 缓存(Cache)是一种用空间换取时间的技术 存在于计算机中很多地方,用来将一些慢速设备中的常用数据保存在快速设备中,取数据的时候直接从快速设备中取. 比如CPU二级缓存.内存.windows文件读取缓存. 2. .NE

HttpResponseCache的使用缓存cache

为什么要用cache? 我们可以通过传递类似上次更新时间这样的参数来制定查询某些数据.同样,在下载图片的时候,server那边最好能够减少图片的大小,而不是让我们下载完整大小的图片. 之前我们在软件开发中,cache都是自己来写,不管是图片缓存还是其他从网络获取的数据,有了HttpResponseCache,它帮助我们可以很好的解决cache这个问题(我现在感觉他只适合cache一些小的数据,如果大量的图片cache还是自己缓存到SD卡上面去比较好). HttpResponseCache的好处:

ASP.NET缓存 Cache

缓存介绍 如果每次进入页面的时候都查询数据库生成页面内容的话,如果访问量非常大,则网站性能会非常差,而如果只有第一次访问的时候才查询数据库生成页面内容,以后都直接输出内容,则能提高系统性能,这样无论多少人访问都只访问一次数据库,数据库压力不变缓存是一种用空间换取时间的技术,存在于计算机中很多地方,用来将一些慢速设备中的常用数据保存在快速设备中,取数据的时候直接从快速设备中取,比如CPU二级缓存,WINDOWS文件读取缓存缓存存在失效的问题:为了保证从缓存中读取数据和慢速数据中数据一致,则需要在慢

POCO库——Foundation组件之缓存Cache

缓存Cache:内部提供多种缓存Cache机制,并对不同机制的管理缓存策略不同实现: ValidArgs.h :ValidArgs有效键参数类,模板参数实现,_key:键,_isValid:是否有效,此外提供key获取键.isValid是否键有效,invalidate使得键值无效:默认情况下键为有效: KeyValueArgs.h :KeyValueArgs键值参数对类,模板参数实现,_key:键,_value:键值:此外提供key获取键,value获取键值: EventArgs.h :事件参数

asp.net,缓存Cache

缓存Cache: 1>直接使用Cache["content"],缓存与Session不同,所有用户都可以共享.永不过期,由服务器自己维护,当内存不够时,会将老的缓存释放掉. 2>设置绝对过期日期.Cache.Insert("nowTime", DateTime.Now, null, DateTime.Now.AddSeconds(7), TimeSpan.Zero); 3>设置滑动过期日期: Cache.Insert("nowTime&q

缓存(Cache)

什么是缓存? web应用程序可被多个用户访问.当用户少,负载低时,可提供快速的访问.当负载成倍增加时,响应就慢下来了.服务器响应慢是高负载网站最常见的问题.为了解决这个问题,我们常采用升级硬件配置,负载均衡,增加带宽等措施.但下载并不是响应慢的唯一原因.我们需要提供一种加快数据访问的机制,进而提升网站的性能.缓存提供了这种解决方案.缓存是种技术.我们可以把频繁使用的数据缓存或把网页临时缓存在本地硬盘为了以后再次访问.在大量用户访问一个站点或一个用户多次访问站点时,缓存技术能加快响应.缓存可以出现

网页的缓存Cache与控制

什么是缓存 Cache? 缓存位于客户端与服务器之间, 或者服务器与服务器之间.它决定是否保存所获资源的副本,以及如何使用副本,何时更新副本,这里所说的资源包括页面的HTML, 图片,文件等等. 使用缓存主要有2大理由: 减少响应延迟,让页面显示更快:因为缓存比源服务器离客户端更近, 如果直接从缓存而不是源服务器响应客户的请求,耗时更少,让网站看上去响应更快: 减少网络带宽消耗:当副本被重用时,减少了从源服务器获取资源的次数,从而减少带宽消耗. 缓存如何工作? 所有的缓存都遵循以下基本规则 保留

Java 中常用缓存Cache机制的实现

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. 所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. 缓存主要可分为二大类: 一.通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式: 二.内存缓存,也就是实现一个类中静态Map,对这个Map进行

Java -- 常用缓存Cache机制的实现 -- 艺多不压身

常用缓存Cache机制的实现 缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例. 这样做可以减少系统开销,提高系统效率. 缓存主要可分为二大类: 一.通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式 二.内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查. 啦啦啦