用于A模块读B模块数据,A模块内部缓存。
缓存区内使用两组Map对象:bufferMap对象保存key,value值对,为数据保存对象;chooseMap对象保存key,time值对,维持数据更新,在缓存区满时踢出较老数据。
private Map<Object, Object> bufferMap = null; // 存储数据 private Map<Object, Long> chooseMap = null; // 判断退出数据
一组读写锁,用于读写操作控制。
private final ReadWriteLock bufferLock = new ReentrantReadWriteLock(false); private Lock bufferReadLock = null; private Lock bufferWriteLock = null;
读缓存方法,当缓存内部有所要读对象时,返回所读对象。当找不到对象时,返回null。读方法内部分为两步操作,首先从bufferMap中读取key对象,当读取成功后,在chooseMap中标记key对象为当前最新对象(count为全局int对象,用于记录缓存区内最新对象)。读结束后返回所读对象。
public Object readBuffer(Object key) { Object tmp = null; try { bufferReadLock.lock(); //加读锁,控制读过程 tmp = bufferMap.get(key); } finally { bufferReadLock.unlock(); //解读锁 } try { bufferWriteLock.lock(); //chooseMap对象内容需要写改变,加写锁 if (tmp != null) chooseMap.put(key, ++count); } finally { bufferWriteLock.unlock(); //解写锁 } return tmp; }
cleanBuffer()用于在缓存已满时清理掉最老数据。
private void cleanBuffer() { Long miniCount = Long.MAX_VALUE; //miniCount用于指向缓存区中最小数据 Map<Long, Object> tmpChooseMap = new HashMap<Long, Object>(bufferSize); for (Map.Entry<Object, Long> entry : chooseMap.entrySet()) { if (miniCount > entry.getValue()) { miniCount = entry.getValue(); } //将chooseMap键值对反向存储至tmpChooseMap,方便查找出当前最小数据key值 tmpChooseMap.put(entry.getValue(), entry.getKey()); } int i;//由于chooseMap内键值对存储了key递增过程值,因此使用计数排序,对最小部分删除,保留部分排序 for (i = 0; i < (bufferSize * (1 - removeParameter)); i++, miniCount++) { Object key1 = tmpChooseMap.get(miniCount); //获取当前最小值对应key if (key1 == null) {//判断是否取到,防止跳值 i--; continue; } chooseMap.remove(key1); //移出缓存区 bufferMap.remove(key1); } for (Long j = (long) 0; i < bufferSize; i++, miniCount++, j++) { Object key1 = tmpChooseMap.get(miniCount); //对缓存区剩下值重新计数排序 if (key1 == null) { i--; j--; continue; } chooseMap.put(key1, j); } count = (long) bufferMap.size(); //设置最新计数值 }
移除单个对象方法,从缓存区中移除key值对应对象
public void remove(Object key) { try { bufferWriteLock.lock(); bufferMap.remove(key); chooseMap.remove(key); } finally { bufferWriteLock.unlock(); } }
清空缓存区方法
public void removeAll() { try { bufferWriteLock.lock(); bufferMap.clear(); chooseMap.clear(); } finally { bufferWriteLock.unlock(); } }