Java 语言设计一个缓存模型

前提:

数据库表 student:

create table student(
	id int,
	name varchar(15)
);

一.线程不安全版本

import java.util.HashMap;
import java.util.Map;
 
public class CacheDemo {
 
    //map 用来作缓存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
 
    //根据 key 的值,返回其对应的 value
    public  static Object getValue(String key) {
        Object value = map.get(key);
        if (value == null) {
        	int ID=Integer.value(key);
            value =//去数据库查询该 key 对应的 value ( select name from student where id=ID;)
            map.put(key, value);  //将数据放到缓存模型中
        }
        return value;   //map 中存在该 key 对应的值那么则返回
    }
}

从上面的代码可以看出,当有 10 个线程同时访问数据库的时候,会出现数据查询的次数也是10次,这样对数据库的访问压力过大,不推荐使用。


二.线程安全版本

import java.util.HashMap;
import java.util.Map;
 
public class CacheDemo {
 
    // map 用来作缓存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
 
    public synchronized static Object getValue(String key) {
        Object value = map.get(key);
        if (value == null) {
            value = //去数据库查询该 key 对应的 value ( select name from student where id=ID;)
            map.put(key, value);   //将数据放到缓存模型中
        }
        return value;
    }
}

从上面的代码可以看出,在 getValue() 方法上加上 synchronized 后,当有 10 个线程(10 个线程携带的 key 值都一样)都要访问数据库的时候,线程之间只有抢到了锁的线程才可以访问数据库进行数据查询,因此一定程度上减少了数据库访问压力,但是锁的粒度比较大。


三.升级版本

import java.util.HashMap;
import java.util.Map;
 
public class CacheDemo {
 
    // map 用来作缓存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
 
    public static Object getValue(String key) {
        Object value = map.get(key);
        if(value==null){
            synchronized (CacheDemo.class){
                if(value==null){
                    value="abc";    //去数据库查询该 key 对应的 value ( select name from student where id=ID;)
                    map.put(key,value);//将数据放到缓存模型中
                }
            }
        }
        return value;
    }
}

从上面的代码可以看出,如果 10 个线程(10 个线程携带的 key 值都一样)访问的数据已经存在于 map 中了,那么就不会出现竞争锁的情况,直接返回 value 即可。但是如果线程访问的数据不存在于 map 中的时候,才会出现竞争锁的情况然后进行数据库的查询,并且只有第一个抢到锁的线程才可以查询数据库,其他的线程拿到锁以后,发现 value 已经不为 null 了,直接返回 value 的值即可。

原文来源:https://blog.csdn.net/u010452388/article/details/82725299

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值