1、通过ReentrantReadWriteLock、ConcurrentHashMap实现一个简易缓存。
2、通过TimerTask或Thread回收缓存。
package mvc.framework.cache; import java.util.LinkedList; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // 缓存管理器 public class CacheManager { private static final Logger LOGGER = LoggerFactory.getLogger(CacheManager.class); private CacheManager() { } // 缓存清理周期 private long evictionIntervalTimer = 1 * 60 * 1000L; // 是否开启清除失效缓存 private volatile Boolean clearExpireCacheEnable = true; // 缓存失效时间 private long cacheTimeout = 12 * 60 * 60 * 1000L; // 缓存使用记录 LRU(Least recently used)最近最少使用算法 private static LinkedList<Object> cacheLruList = new LinkedList<>(); // 缓存池容量 private static Integer cacheMaxSize = 1024; // 缓存池 private final static Map<Object, CacheEntry> cacheHashMap = new ConcurrentHashMap<>(); // 读写锁 private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); private static Lock writeLock = reentrantReadWriteLock.writeLock(); private static Lock readLock = reentrantReadWriteLock.readLock(); @SuppressWarnings("unused") private void init() { initClearTask(); } // 自定义缓存失效时间 @SuppressWarnings("unused") private void init(long cacheTimes) { this.cacheTimeout = cacheTimes; initClearTask(); } private void initClearTask() { // 启动清除失效缓存数据 if (clearExpireCacheEnable) { // 线程Thread方式 //new ClearCacheTask().start(); // 定时器TimerTask方式 Timer timer = new Timer(); ClearTimerTask timerTask = new ClearTimerTask(); // 程序运行后,延迟15秒执行,每隔evictionIntervalTimer重复执行 timer.schedule(timerTask, 15, evictionIntervalTimer); } } // 缓存实例 private static CacheManager getCacheManagerInstance() { return CacheManagerFactory.cacheManager; } // 缓存工厂 private static class CacheManagerFactory { private static final CacheManager cacheManager = new CacheManager(); } // 定时器TimerTask方式 private class ClearTimerTask extends TimerTask { { LOGGER.debug("ClearTimerTask init"); } @Override public void run() { try { LOGGER.debug("ClearTimerTask exec"); long now = System.currentTimeMillis(); for (Object key : cacheHashMap.keySet()) { try { writeLock.lock(); // 判断使用记录中的key是否已经被LRU清除 if (!cacheLruList.contains(key)) { return; } CacheEntry entry = cacheHashMap.get(key); if (now - entry.lastTouchTime >= cacheTimeout) { cacheHashMap.remove(key); cacheLruList.remove(key); LOGGER.debug("remove key:" + key); } } finally { writeLock.unlock(); } } } catch (Exception e) { LOGGER.debug(e.toString()); } } } // 线程Thread方式 @SuppressWarnings("unused") private class ClearCacheTask extends Thread { { LOGGER.debug("ClearCacheTask init"); } @Override public void run() { while (clearExpireCacheEnable) { try { LOGGER.debug("ClearTimerTask exec"); long now = System.currentTimeMillis(); // 定时清理 try { Thread.sleep(evictionIntervalTimer); } catch (Exception e) { e.printStackTrace(); } for (Object key : cacheHashMap.keySet()) { try { writeLock.lock(); // 判断使用记录中是否存在 if (!cacheLruList.contains(key)) { return; } CacheEntry entry = cacheHashMap.get(key); if (now - entry.lastTouchTime >= cacheTimeout) { cacheHashMap.remove(key); cacheLruList.remove(key); LOGGER.debug("remove key:" + key); } } finally { writeLock.unlock(); } } } catch (Exception e) { LOGGER.debug(e.toString()); } } } } // CacheEntry实体 private class CacheEntry { long lastTouchTime; Object value; CacheEntry(Object value) { super(); this.value = value; } public void setLastTouchTime(long currentTimeMillis) { this.lastTouchTime = System.currentTimeMillis(); } } // 赋值 public Object put(Object key, Object value) throws Exception { // 判断缓存大小是否够用,否则根据LRU删除 if (cacheHashMap.size() > cacheMaxSize) { delete(); } CacheEntry entry = new CacheEntry(value); writeLock.lock(); try { cacheHashMap.put(key, entry); cacheLruList.addFirst(key); } finally { writeLock.unlock(); } return value; } // 取值 public Object get(Object key) { readLock.lock(); CacheEntry entry = null; try { entry = cacheHashMap.get(key); } finally { readLock.unlock(); } if (entry == null) { return null; } // 更新CacheEntry缓存访问时间 updateCacheTime(entry); // 更新使用记录 updateCacheLruList(key); return entry == null ? null : entry.value; } // 更新缓存访问时间 public static void updateCacheTime(CacheEntry entry) { writeLock.lock(); try { entry.setLastTouchTime(System.currentTimeMillis()); } finally { writeLock.unlock(); } } // 更新缓存使用记录 public static void updateCacheLruList(Object key) { writeLock.lock(); try { // 删除使用记录 cacheLruList.remove(key); // 新增使用记录到首位 cacheLruList.addFirst(key); } finally { writeLock.unlock(); } } // 删除最近最少使用的缓存 public static void delete() { Object cacheKey = null; writeLock.lock(); try { cacheKey = cacheLruList.get(cacheLruList.size() - 1); cacheLruList.remove(cacheLruList.size() - 1); cacheHashMap.remove(cacheKey); LOGGER.debug("lru remove key:" + cacheKey); } finally { writeLock.unlock(); } } // 删除 public static void delete(Object key) { if (key == null) return; writeLock.lock(); try { cacheHashMap.remove(key); cacheLruList.remove(key); } finally { writeLock.unlock(); } } // 清空 public static void clear() { writeLock.lock(); try { cacheHashMap.clear(); cacheLruList.clear(); } finally { writeLock.unlock(); } } // 测试 public static void main(String[] args) throws Exception { CacheManager cacheManager = CacheManager.getCacheManagerInstance(); //cacheManager.init(3 * 60 * 1000L); cacheManager.init(); for (int i = 0; i < 10; i++) { cacheManager.put(i, i); } cacheManager.get(1); cacheManager.get(3); } }