基于LinkedList和Map实现LRUCache和SoftLRUCache

Reference

public class Reference {
    //1M
    private final byte[] data = new byte[2<<19];
    protected void finalize() throws Exception{
        System.out.println("the reference will be GC");
    }
}

LRUCache

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/***
 *
 * LRU:  least recently used, 最近最少使用
 */
public class LRUCache<K, V> {

    /**
     * 用于记录key值的顺序
     */
    private final LinkedList<K> keyList = new LinkedList<>();

    /**
     * 用户存储数据
     */
    private final Map<K, V> cache = new HashMap<>();

    /**
     * cache 最大容量
     */
    private final int capacity;

    private final CacheLoader<K, V> cacheLoader;

    public LRUCache(int capacity, CacheLoader<K, V> cacheLoader) {
        this.capacity = capacity;
        this.cacheLoader = cacheLoader;
    }


    public void put(K key, V value) {

        /**
         * 当元素数量超过容量时,将最老的数据清除
         *
         */
        if (keyList.size() >= capacity) {
            K k = keyList.removeFirst();
            cache.remove(k);
        }

        /**
         * 如果数据已经存在, 则从key的队列中删除
         */

        if (keyList.contains(key)) {
            keyList.remove(key);
        }
        /**
         * 将key存放至队尾
         */
        keyList.addLast(key);
        cache.put(key, value);

    }

    public V get(K key) {

        V value;
        // 先将key从keyList中删除
        boolean remove = keyList.remove(key);
        if (!remove) {
            // 删除失败,表示当前key不存在
            value = cacheLoader.load(key);
            this.put(key, value);
        } else {
            // 如果删除成功,则从cache中返回数据,并将key放入队尾
            value = cache.get(key);
            keyList.addLast(key);
        }
        return value;
    }

    @Override
    public String toString() {
        return this.keyList.toString();
    }

    @FunctionalInterface
    interface CacheLoader<K, V> {
        V load(K k);
    }

}

测试

/**
         * -Xmx128M 最大堆大小
         * -Xms64M  初始化堆大小
         * -XX:+PrintGCDetails 在控制台输出GC详细信息
         *
         * -Xmx128M -Xms64M -XX:+PrintGCDetails
         */
        LRUCache<Integer, Reference> cache = new LRUCache<>(200, key -> new Reference());
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            cache.get(i);
            TimeUnit.SECONDS.sleep(1);
            System.out.println(i + " reference stored to cache");
        }

SoftLRUCache

package com.james.example.thread.jcp_multithread_architecture.chapter25;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/***
 *
 * LRU:  least recently used, 最近最少使用
 */
public class SoftLRUCache<K, V> {

    /**
     * 用于记录key值的顺序
     */
    private final LinkedList<K> keyList = new LinkedList<>();

    /**
     * 用户存储数据
     * value 采用SoftReference修饰
     */
    private final Map<K, SoftReference<V>> cache = new HashMap<>();

    /**
     * cache 最大容量
     */
    private final int capacity;

    private final CacheLoader<K, V> cacheLoader;

    public SoftLRUCache(int capacity, CacheLoader<K, V> cacheLoader) {
        this.capacity = capacity;
        this.cacheLoader = cacheLoader;
    }


    public void put(K key, V value) {

        /**
         * 当元素数量超过容量时,将最老的数据清除
         *
         */
        if (keyList.size() >= capacity) {
            K k = keyList.removeFirst();
            cache.remove(k);
        }

        /**
         * 如果数据已经存在, 则从key的队列中删除
         */

        if (keyList.contains(key)) {
            keyList.remove(key);
        }
        /**
         * 将key存放至队尾
         */
        keyList.addLast(key);
        /**
         * 保存SoftReference
         */
        cache.put(key, new SoftReference<>(value));

    }

    public V get(K key) {

        V value;
        // 先将key从keyList中删除
        boolean remove = keyList.remove(key);
        if (!remove) {
            // 删除失败,表示当前key不存在
            value = cacheLoader.load(key);
            this.put(key, value);
        } else {
            // 如果删除成功,则从cache中返回数据,并将key放入队尾
            value = cache.get(key).get();// 调用SoftReference.get 方法获取
            keyList.addLast(key);
        }
        return value;
    }

    @Override
    public String toString() {
        return this.keyList.toString();
    }

    @FunctionalInterface
    interface CacheLoader<K, V> {
        V load(K k);
    }

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值