剛纔我弄了一下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