1.防止订单重复提交
使用 redis 分布式锁来实现,可以使用用户ID,加购物车的商品ID,使用 MD5算法,得出一个key 作为分布式锁的key。解决问题的关键是 保持分布式锁的 key 的唯一性。
2. 缓存击穿
如果用户查的ID数据库没有值,那么缓存就击穿了,解决办法,如果数据库没有值,也给他缓存一个空值,第二次 在访问的时候,就直接给他返回null
private String Empty="-1";
public Product getProduct(String productId){
Object obj= cache.get(productId);
if(obj!=null){
if(obj instantOf(Product.class)){
return (Product)obj;
}
if(Empty.equals(obj)){
return null
}
}
Product p=dao.get(productId);
if(p!=null){
cache.put(productId,p);
}
else{
cache.put(productId,Empty);
}
return p;
}
这个方法有个问题,如果大量的 空存在会 损耗 内存,那么空缓存可以设置一个缓存过期时间,过一段时间缓存就会被清理掉。
还可以使用布隆过滤器。
- 热点数据访问。
//双重检测锁
Product getProduct(String productId){
Object obj= cache.get(productId);
if(obj!=null){
if(obj instantOf(Product.class)){
return (Product)obj;
}
if(Empty.equals(obj)){
return null
}
}
synchronized(this){
Object obj= cache.get(productId);
if(obj!=null){
if(obj instantOf(Product.class)){
return (Product)obj;
}
if(Empty.equals(obj)){
return null
}
}
Product p=dao.get(productId);
if(p!=null){
cache.put(productId,p);
}
else{
cache.put(productId,Empty,60000);
}
}
return p;
}
synchronized 性能提升
synchronized 锁定时,需要注意锁的对象。
如果在 spring 使用
// 这个代码会锁定当前控制器的实例对象,因为控制器实例是单例对象,因此效率不高。
synchronized(this){
}
性能提升
CurrentHashMap map=new CurrentHashMap();
public void save(String userId){
//产生锁对象
Object o=map.computeIfAbsent(userId,o->new Object());
//这样就每个用户ID就持有有一把锁。
synchronized(o){
}
}
标签:Product,obj,cache,问题,面试,return,null,productId
From: https://www.cnblogs.com/yg_zhang/p/18475596