刚才我弄了一下EhCache
底层有用链表实现的,并且默认使用lru算法来提高效率,当把元素放进去的时候,会先放到头部链表
然后在使用数据的时候,会从头部查找这个数据,然后把找到的数据放到头部,然后返回
并且还会开启线程来定时从尾部清理节点
看代码吧
public void put(String key, Object val) {
if(headNode==null){
CacheNode cacheNode=new CacheNode(key,val,tailNode,null);
headNode=cacheNode;
System.out.println("头部初始化");
return;
}
if(tailNode==null){
CacheNode cacheNode=new CacheNode(key,val,null,headNode);
tailNode=cacheNode;
System.out.println("尾部初始化");
return;
}
//直接插入到尾部
CacheNode cacheNode = new CacheNode();
cacheNode.setKey(key);
cacheNode.setVal(val);
//放到头部的,搞错了
headNode.setLast(cacheNode);
cacheNode.setNext(headNode);
headNode=cacheNode;
size++;
System.out.println("放进去了");
}
先看头部和尾部是否为空,如果都不为空就直接把节点放到头部
然后就是获取数据的方法
public Object get(String key) {
if(size==0){
return null;
}
if (headNode.getKey().equals(key))
return headNode.getVal();
//遍历节点找到使用了这个key的
for (CacheNode cacheNode = headNode; cacheNode != null; cacheNode = cacheNode.getNext()) {
if (cacheNode.getKey().equals(key)) {
//找到了就把这个节点放到头部,然后把结果返回给调用者
switchToHead(cacheNode);
return cacheNode.getVal();
}
}
return null;
}
如果找到节点后,就把这个节点放到头部,然后把节点返回给调用者
下面是把节点放到头部的方法
简单的引用指向
private void switchToHead(CacheNode cacheNode) {
if (cacheNode.getLast() != null) {
CacheNode last = cacheNode.getLast();
if (cacheNode.getNext() != null) {
//处理他前面和后面的节点
CacheNode next = cacheNode.getNext();
next.setLast(last);
last.setNext(next);
}
//直接和头部交换就行
headNode.setLast(cacheNode);
headNode = cacheNode;
return;
}
//如果前面是空的,那说明你已经是头了,我就不管你
}
接下来就是定时清理的方法
private void doClean(CacheNode cacheNode, int needCount) {
if (size <= needCount)
return;
//开始清理
if (cacheNode.getLast() == null) {
cacheNode = null;
return;
}
cacheNode.getLast().setNext(null);
cacheNode = null;
System.out.println("----------清理掉一个");
size--;
if(cacheNode==null||cacheNode.getLast()==null)
return;
doClean(cacheNode.getLast(), needCount);
}
就是定时从尾部开始清理节点,直到要清理的大小不满足条件
然后就是方法的调用
CacheChain cacheChain=new CacheChain();
cacheChain.put("a",new Student("zhangjun","zhangjun249",19));
cacheChain.put("b",new Student("asdf","zhangjun249",19));
cacheChain.put("c",new Student("zhanasdgjun","zhangjun249",19));
cacheChain.put("d",new Student("asdf","zhangjun249",19));
cacheChain.put("e",new Student("fffffff","zhangjun249",19));
cacheChain.put("f",new Student("aaaaaaaaaaa","zhangjun249",19));
cacheChain.cleanNode(3000,2);
System.out.println(cacheChain.get("a")!=null);
完整代码可以去我的GitHub