阿里笔试题手写线程安全的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方法在多线程并发场景下会降低并发性能。