public class LazyRemovalCache<K,V> {
/**
* 缓存对象的hashMap
*/
private final ConcurrentMap<K,Entry<V>> map=new ConcurrentHashMap<K,Entry<V>>();
/** Max number of elements, if exceeded, we remove all elements marked as removable and older than max_age ms
* 缓存允许的最大条目
* */
private final int max_elements;
/**
* 缓存对象的最大生命周期
*/
private final long max_age;
/**
* 打印函数接口
* @author Administrator
*
* @param <K>
* @param <V>
*/
public interface Printable<K,V> {
String print(K key,V val);
}
/**
* 无参构造函数
*/
public LazyRemovalCache() {
this(200, 5000L);
}
/**
* 带参数的构造函数
* @param max_elements
* @param max_age
*/
public LazyRemovalCache(int max_elements, long max_age) {
this.max_elements=max_elements;
this.max_age=max_age;
}
/**
* 缓存中添加缓存对象
* @param key
* @param val
*/
public void add(K key, V val) {
if(key != null && val != null)
map.put(key, new Entry<V>(val)); // overwrite existing element (new timestamp, and possible removable mark erased)
checkMaxSizeExceeded();
}
/**
* 得到一个缓存对象
* @param key
* @return
*/
public V get(K key) {
if(key == null)
return null;
Entry<V> entry=map.get(key);
return entry != null? entry.val : null;
}
/**
* 根据缓存对象得到缓存KEY值
* @param val
* @return
*/
public K getByValue(V val) {
if(val == null) return null;
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
Entry<V> v=entry.getValue();
if(v.val != null && v.val.equals(val))
return entry.getKey();
}
return null;
}
/**
* 删除一个缓存对象
* @param key
*/
public void remove(K key) {
remove(key, false);
}
/**
* 删除缓存对象
* @param key
* @param force true:强制删除,false:非强制删除
*/
public void remove(K key, boolean force) {
if(key == null)
return;
if(force)
map.remove(key);
else {
Entry<V> entry=map.get(key);
if(entry != null)
entry.removable=true;
}
checkMaxSizeExceeded();
}
/**
* 删除一个集合的缓存的key值
* @param keys
*/
public void removeAll(Collection<K> keys) {
removeAll(keys, false);
}
public void removeAll(Collection<K> keys, boolean force) {
if(keys == null || keys.isEmpty())
return;
if(force)
map.keySet().removeAll(keys);
else {
for(K key: keys) {
Entry<V> entry=map.get(key);
if(entry != null)
entry.removable=true;
}
}
checkMaxSizeExceeded();
}
/**
* 清空缓存对象
* @param force true:强制清空,false:非强制清空
*/
public void clear(boolean force) {
if(force)
map.clear();
else {
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
Entry<V> val=entry.getValue();
if(val != null) {
Entry<V> tmp=entry.getValue();
if(tmp != null)
tmp.removable=true;
}
}
}
}
public void retainAll(Collection<K> keys) {
retainAll(keys, false);
}
/**
* 移除交集的key值
* @param keys
* @param force
*/
public void retainAll(Collection<K> keys, boolean force) {
if(keys == null || keys.isEmpty())
return;
if(force)
map.keySet().retainAll(keys);
else {
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
if(!keys.contains(entry.getKey())) {
Entry<V> val=entry.getValue();
if(val != null)
val.removable=true;
}
}
}
checkMaxSizeExceeded();
}
/**
* 得到Key值set数组
* @return
*/
public Set<V> values() {
Set<V> retval=new HashSet<V>();
for(Entry<V> entry: map.values()) {
retval.add(entry.val);
}
return retval;
}
/**
* 得到缓存的内容
* @return
*/
public Map<K,V > contents() {
Map<K,V> retval=new HashMap<K,V>();
for(Map.Entry<K,Entry<V>> entry: map.entrySet())
retval.put(entry.getKey(), entry.getValue().val);
return retval;
}
public int size() {
return map.size();
}
public String printCache() {
StringBuilder sb=new StringBuilder();
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
}
return sb.toString();
}
public String printCache(Printable print_function) {
StringBuilder sb=new StringBuilder();
for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {
K key=entry.getKey();
V val=entry.getValue().val;
sb.append(print_function.print(key, val));
}
return sb.toString();
}
public String toString() {
return printCache();
}
private void checkMaxSizeExceeded() {
if(map.size() > max_elements) {
removeMarkedElements();
}
}
/**
* Removes elements marked as removable
* 删除掉被标志删除的元素
*
*/
public void removeMarkedElements() {
long curr_time=System.currentTimeMillis();
for(Iterator<Map.Entry<K,Entry<V>>> it=map.entrySet().iterator(); it.hasNext();) {
Map.Entry<K, Entry<V>> entry=it.next();
Entry<V> tmp=entry.getValue();
if(tmp.removable && (curr_time - tmp.timestamp) >= max_age) {
it.remove();
}
}
}
/**
*
* @author 缓存条目的封装类
*
* @param <V>
*/
private static class Entry<V> {
/**
* 缓存的对象
*/
private final V val;
/**
* 时间戳
*/
private final long timestamp=System.currentTimeMillis();
/**
* 是否被移除的标志
*/
private boolean removable=false;
public Entry(V val) {
this.val=val;
}
public String toString() {
return val + " (" + (System.currentTimeMillis() - timestamp) + "ms old" + (removable? ", removable" : "") + ")";
}
}
}
分享到:
相关推荐
本篇文章主要介绍了Java中LocalCache本地缓存实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Java利用ConcurrentHashMap实现本地缓存demo; 基本功能有缓存有效期、缓存最大数、缓存存入记录、清理线程、过期算法删除缓存、LRU算法删除、获取缓存值等功能。 复制到本地项目的时候,记得改包路径哦~
利用spring实现的简单的缓存的例子,代码解释:http://blog.csdn.net/maoyeqiu/article/details/50238035
本文实例讲述了微信小程序基于本地缓存实现点赞功能的方法。分享给大家供大家参考,具体如下: wxml中的写法 注意: 1. 使用wx:if={{condition}} wx:else实现图标的切换效果; 2. 为图片绑定点击事件bindtap=to...
非常方便好用的http连接框架,可以方便的发起连接,所有连接的结果都会保存在本地,下次调用时直接从本地读取
JS localStorage实现本地缓存的方法,需要的朋友可以参考一下
Kotlin缓存Kotlin中的缓存实现可以在代码中本地使用。 这个想法是要消除开发人员为每个项目创建的恒定缓存。 当前实现:永久性快取永久缓存是一个简单的缓存,它将无限期保存该值。用法val cache = PermanentCache ...
本篇文章主要介绍了Java本地缓存的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
使用sqlite数据库本地缓存
基于java的map和timer实现本地缓存及定时清理失效缓存的功能 本项目仅用于初学者学习使用 初学者可基于此项目初步了解缓存实现的基本原理 后期在项目中使用建议使用现成的缓存框架:redis、ehcache等
主要介绍了实现 Java 本地缓存的方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Springboot集成本地缓存Guava本章介绍一个比较好用的本地缓存Guava0x01、添加依赖0x02、添加GuavaLocalCache提供了设置超时时
一个ListView异步加载并实现图片在本地缓存的例子。
操作系统实验之第二高速缓存方式实现文件读写操作。
c#版本的本地缓存,K-V缓存,实现一般缓存接口。实现FIFO,LRU,LFU策略。通过配置类设置缓存信息,主要设置maxcachesize,cachetime
主要介绍了如何基于LoadingCache实现Java本地缓存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
一、概述 缓存的思想可以应用在软件分层的各个层面。它是一种内部机制,对外界而言,是不可感知的。 数据库本身有缓存,持久层也可以缓存...二、缓存实现(浏览器缓存当前访问的JSP动态页面) (一)、服务端方法: 代
自Spring 5开始,Caffeine已成为默认的缓存实现,取代了原先的Google Guava。官方资料显示,Caffeine的缓存命中率已接近理论最优值。实际上,Caffeine与ConcurrentMap在功能上有许多相似之处,都支持并发操作,且...
android之清理缓存实现,供大家参考,具体内容如下 一. 清理缓存首先要搞清楚清理哪些东西 1、app本身的功能比如录像,录音,更新都会产生文件,需要清理 2、app的默认缓存地址cache 二. 搞清楚要清理的文件夹位置 1、...