阿里笔试题手写线程安全的LRU缓存

笔试题目:
1) 实现一个KV型的LRU(最近最少使用)Cache,支持get和put方法;要求实现时间复杂度,O(1); 
2) 如果要求get,put方法线程安全,又该如何支持?请用代码实现,并说明如此实现的性能优缺点,语言不限;

/*
public class LRUCache {
  public String get(String key){
  }
  public void put(String key, String value){
  }
}
*/

public class LRUCache extends LinkedHashMap<String,String>{
   
    private int cache_size;

    public LRUCache(int capacity){
      super(capacity, 0.75f, true);
      this.cache_size = capacity;

    }

    public String get(String key){
      synchronized (LRUCache.class) {
        return super.getOrDefault(key, "");
      }
    }  

    public String put(String key, String value){
      synchronized (LRUCache.class) {
        return super.put(key, value);
      }
    }  

    @Override
    protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
      return this.size() > cache_size;
    }  
}

后来面试官又要求我用单例模式写一个,没办法,那就来一个吧

public class LRUCache extends LinkedHashMap<String, String> {

    private int cache_size;

    private static LRUCache instance;

    private LRUCache(int capacity) {
        super(capacity, 0.75f, true);
        this.cache_size = capacity;

    }

    public static synchronized LRUCache getInstance() {
        if (instance == null) {
            instance = new LRUCache(100);
        }
        return instance;
    }

    public String get(String key) {
        synchronized (this) {
            return super.getOrDefault(key, "");
        }
    }

    public String put(String key, String value) {
        synchronized (this) {
            return super.put(key, value);
        }
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
        return this.size() > cache_size;
    }
}

说明:

1、LRUCache采用单例模式(缓存对象只有一个),私有构造方法,synchronized同步静态方法获取实例对象,保证创建实例时线程安全。
2、get和put方法中使用synchronized同步代码块的方式来解决get和put方法的线程安全的问题。
3、由于LRUCache是单例,synchronized(this)同步代码块是能保证线程安全的,但是get和put方法在多线程并发场景下会降低并发性能。

 

posted @ 2020-08-21 10:44  gaopengpy  阅读(1181)  评论(0编辑  收藏  举报