자바 가 Redis 의 LRU 캐 시 메커니즘 을 어떻게 실현 하 는 지 간단히 말 하 다

6170 단어 자바LRU캐 시
LRU 개요
최근 에 사용 한 것 은 앞 에 두 고 최근 에 사용 하지 않 은 것 은 뒤에 두 어야 합 니 다.만약 에 새로운 숫자 가 왔 다 면 메모리 가 가득 차 면 오래된 숫자 를 도태 시 켜 야 합 니 다.그러면 데 이 터 를 이동 하기 편리 하도록 링크 와 유사 한 데이터 구 조 를 사용 해 야 합 니 다.게다가 이 데이터 가 최신 또는 최신 이 아니 라 는 것 을 판단 하려 면 hashmap 등 key-value 형식의 데이터 구 조 를 사용 해 야 합 니 다.
링크 드 HashMap 으로 구현 

package thread;
import java.util.LinkedHashMap;
import java.util.Map;
 
public class LRUCacheTest {
    int capacity;
    Map<Integer,Integer> map;
 
    public LRUCacheTest(int capacity){
        this.capacity = capacity;
        map = new LinkedHashMap<>();
    }
 
    public int get(int key){
        //    
       if(!map.containsKey(key)){
          return -1;
       }
       Integer value = map.remove(key);
       map.put(key,value);
       return value;
    }
 
    public void put(int key,int value){
        if(map.containsKey(key)){
           map.remove(key);
           map.put(key,value);
           return;
        }
        map.put(key,value);
        //  capacity,           ,      removeEldestEntry  
        if(map.size() > capacity){
           map.remove(map.entrySet().iterator().next().getKey());
        }
 
    }
 
    public static void main(String[] args) {
        LRUCacheTest lruCache = new LRUCacheTest(10);
        for (int i = 0; i < 10; i++) {
            lruCache.map.put(i,i);
            System.out.print(lruCache.map.size()+"\t");
        }
        System.out.println();
        System.out.println(lruCache.map);
        lruCache.put(10,200);
        System.out.println(lruCache.map);
        lruCache.put(11,100);
        System.out.println(lruCache.map);
        lruCache.get(2);
        System.out.println(lruCache.map);
    }
 
}






결 과 를 보면 정확 하 다.현재 시간 에서 가장 먼 데이터 가 도태 되 었 다.
링크 드 HashMap 간단 한 방법 으로 구현
링크 드 하 쉬 맵 은 양 방향 링크 를 유지 하 는 하 쉬 맵 으로 요 소 를 삽입 하 는 순 서 를 유지 합 니 다.
링크 드 HashMap 은 새로 요 소 를 삽입 한 후에 가장 오래된 요 소 를 삭제 할 지 여 부 를 결정 할 수 있 는 갈고리 방법 을 제공 합 니 다.
복사 removeEldestEntry 구현

package thread;
import java.util.LinkedHashMap;
import java.util.Map;
 
public class LRUByLinkedHashMap extends LinkedHashMap<Integer,Integer> {
    /**
     * LRU       
     */
    private int maxSize;
 
    public LRUByLinkedHashMap(int maxSize) {
        //       /0.75,        maxSize
        // accessOrder=true        ,           
        super((int) Math.ceil(maxSize / 0.75) + 1, 0.75f, true);
        this.maxSize = maxSize;
    }
 
    /**
     *         ,map           
     *      true          
     * @param eldest
     * @return
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > maxSize;
    }
 
    public static void main(String[] args) {
        LRUByLinkedHashMap hashMap = new LRUByLinkedHashMap(10);
        for (int i = 0; i < 10; i++) {
            hashMap.put(i,i);
            System.out.print(hashMap.size()+"\t");
        }
        System.out.println();
        System.out.println(hashMap);
        hashMap.put(10,200);
        System.out.println(hashMap);
        hashMap.put(11,100);
        System.out.println(hashMap);
        hashMap.get(10);
        System.out.println(hashMap);
    }
 
}

더 블 링크+hashmap

package thread;
import java.util.HashMap;
import java.util.Map;
 
public class LRURedis {
    private int capacity;
    private Map<Integer,ListNode> map;
    private ListNode head;
    private ListNode tail;
 
    public LRURedis(int capacity){
      this.capacity = capacity;
      map = new HashMap<>();
      head = new ListNode(-1,-1);
      tail = new ListNode(-1,-1);
      head.next = tail;
      tail.pre = head;
    }
 
    public int get(int key){
        if(!map.containsKey(key)){
           return -1;
        }
        ListNode node = map.get(key);
        node.pre.next = node.next;
        node.next.pre = node.pre;
        return node.val;
    }
 
    public void put(int key,int value){
        if (get(key)!=-1){
            map.get(key).val = value;
            return;
        }
 
        ListNode node = new ListNode(key,value);
        map.put(key,node);
        moveToTail(node);
 
        if (map.size() > capacity){
            map.remove(head.next.key);
            head.next = head.next.next;
            head.next.pre = head;
        }
 
    }
 
    //        
    private void moveToTail(ListNode node) {
        node.pre = tail.pre;
        tail.pre = node;
        node.pre.next = node;
        node.next = tail;
    }
 
    //        
    private class ListNode{
        int key;
        int val;
        ListNode pre;
        ListNode next;
 
        //       
        public ListNode(int key,int val){
          this.key = key;
          this.val = val;
          pre = null;
          next = null;
        }
    }
}
자바 가 레 디 스 의 LRU 캐 시 체 제 를 어떻게 실현 하 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 가 레 디 스 를 실현 하 는 LRU 캐 시 체제 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기