Java实现LRU(最近最少使用)缓存
2011-03-16 17:38
656 查看
前几天去一个公司面试,面试官直接让上机写一个LRU缓存,当时写的很乱,现整理如下:
重入锁(ReentrantLock)是一种递归无阻塞的同步机制。以前一直认为它是synchronized的简单替代,而且实现机制也不相差太远。不过最近实践过程中发现它们之间还是有着天壤之别。
以下是官方说明:一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。
它提供了lock()方法:
如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
如果当前线程已经保持该锁定,则将保持计数加 1,并且该方法立即返回。
如果该锁定被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁定之前,该线程将一直处于休眠状态,此时锁定保持计数被设置为 1。
package com.jd.test; import java.io.Serializable; import java.util.LinkedHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 缓存类(最近最少未使用) * * @author liuzhenfeng * * @param <K,V> */ public class LRUCache<K, V> extends LinkedHashMap<K, V> implements Serializable { /** * 缓存默认大小 */ public static final int DEFAULT_CAPASITY = 20; /** * 缓存实际大小 */ public static int CACHE_CAPASITY = DEFAULT_CAPASITY; /** * 线程同步锁 */ private static final Lock lock = new ReentrantLock(); public LRUCache() { super(DEFAULT_CAPASITY); CACHE_CAPASITY = DEFAULT_CAPASITY; } public LRUCache(int size) { super(size); CACHE_CAPASITY = size; } /* * 清空緩存 * * @see java.util.LinkedHashMap#clear() */ @Override public void clear() { try { lock.lock(); super.clear(); } finally { lock.unlock(); } } /* * 判断是否包含该对象 * * @see java.util.LinkedHashMap#containsValue(java.lang.Object) */ @Override public boolean containsValue(Object value) { try { lock.lock(); return super.containsValue(value); } finally { lock.unlock(); } } /* * 从缓存中查询对象 * * @see java.util.LinkedHashMap#get(java.lang.Object) */ @Override public V get(Object key) { try { lock.lock(); return super.get(key); } finally { lock.unlock(); } } /* * 是否删除最早未使用缓存对象 * * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) */ @Override protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { try { lock.lock(); return this.size() > CACHE_CAPASITY; } finally { lock.unlock(); } } /* * 判断缓存中是否包含该key * * @see java.util.HashMap#containsKey(java.lang.Object) */ @Override public boolean containsKey(Object key) { try { lock.lock(); return super.containsKey(key); } finally { lock.unlock(); } } /* * 判断缓存是否为空 * * @see java.util.HashMap#isEmpty() */ @Override public boolean isEmpty() { try { lock.lock(); return super.isEmpty(); } finally { lock.unlock(); } } /* * 放入缓存 * * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) */ @Override public V put(K key, V value) { try { lock.lock(); return super.put(key, value); } finally { lock.unlock(); } } /* * 从缓存中删除 * * @see java.util.HashMap#remove(java.lang.Object) */ @Override public V remove(Object key) { try { lock.lock(); return super.remove(key); } finally { lock.unlock(); } } /* * 缓存大小 * * @see java.util.HashMap#size() */ @Override public int size() { try { lock.lock(); return super.size(); } finally { lock.unlock(); } } }
重入锁(ReentrantLock)是一种递归无阻塞的同步机制。以前一直认为它是synchronized的简单替代,而且实现机制也不相差太远。不过最近实践过程中发现它们之间还是有着天壤之别。
以下是官方说明:一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。
它提供了lock()方法:
如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
如果当前线程已经保持该锁定,则将保持计数加 1,并且该方法立即返回。
如果该锁定被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁定之前,该线程将一直处于休眠状态,此时锁定保持计数被设置为 1。
相关文章推荐
- Java实现LRU(最近最少使用)缓存
- Java实现LRU(最近最少使用)缓存
- Java实现LRU(最近最少使用)缓存
- 10行Java代码实现最近被使用(LRU)缓存
- 10行Java代码实现最近被使用(LRU)缓存
- 10行Java代码实现最近被使用(LRU)缓存
- leetcode LRU Cache(高级缓存的最近最少使用算法实现)
- 10 行 Java 代码实现最近被使用( LRU )缓存
- 10行Java代码实现最近被使用(LRU)缓存
- Java-最近被使用缓存(LRU)
- 最近最久未使用页面淘汰算法———LRU算法(java实现)
- map实现最近被使用(LRU)缓存
- 最近最久未使用页面淘汰算法———LRU算法(java实现)
- 缓存淘汰算法--LRU算法【最近最少使用算法LRU置换策略适用于热点数据比较多的场景】
- LRUCache最近最少使用java实现
- Java--缓存热点数据,最近最少使用算法
- Android--LRU缓存实现(Java)
- Java项目开发心得(二):使用EhCache+SSM实现数据缓存
- Java简易LRU缓存实现(开发技巧)
- C++模拟操作系统最近最少使用算法(LRU),acm