java LRUCache
package org.rx.cache; import org.rx.common.*;
import org.rx.beans.DateTime; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.function.Function; import static org.rx.common.Contract.as;
import static org.rx.common.Contract.require;
import static org.rx.util.AsyncTask.TaskFactory; public final class LRUCache<TK, TV> extends Disposable {
private class CacheItem {
public TV value;
private int expireSeconds;
private DateTime createTime;
private Consumer<TV> expireCallback; public CacheItem(TV value, int expireSeconds, Consumer<TV> expireCallback) {
this.value = value;
this.expireSeconds = expireSeconds;
this.expireCallback = expireCallback;
refresh();
} public void refresh() {
if (expireSeconds > -1) {
createTime = DateTime.utcNow();
}
} public void callback() {
if (expireCallback != null) {
expireCallback.accept(value);
}
}
} private static final Lazy<LRUCache<String, Object>> instance = new Lazy<>(() -> new LRUCache<>(1000, 120)); public static LRUCache<String, Object> getInstance() {
return instance.getValue();
} public static Object getOrStore(String key, Function<String, Object> supplier) {
require(key, supplier); return getInstance().getOrAdd(App.cacheKey(key), p -> supplier.apply(key));
} private final Map<TK, CacheItem> cache;
private int maxCapacity;
private int expireSeconds;
private Consumer<TV> expireCallback;
private Future future; public LRUCache(int maxSize, int expireSecondsAfterAccess) {
this(maxSize, expireSecondsAfterAccess, 8 * 1000, null);
} public LRUCache(int maxSize, int expireSecondsAfterAccess, long checkPeriod, Consumer<TV> removeCallback) {
cache = Collections.synchronizedMap(new LinkedHashMap<TK, CacheItem>(maxSize + 1, .75F, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<TK, CacheItem> eldest) {
boolean remove = size() > maxCapacity;
if (remove) {
eldest.getValue().callback();
}
return remove;
}
});
maxCapacity = maxSize;
expireSeconds = expireSecondsAfterAccess;
expireCallback = removeCallback;
future = TaskFactory.schedule(() -> {
for (Map.Entry<TK, CacheItem> entry : NQuery.of(cache.entrySet()).where(p -> p.getValue().expireSeconds > -1
&& DateTime.utcNow().addSeconds(-p.getValue().expireSeconds).after(p.getValue().createTime))) {
entry.getValue().callback();
cache.remove(entry.getKey());
}
}, checkPeriod);
} @Override
protected void freeObjects() {
if (future != null) {
future.cancel(true);
}
cache.clear();
} public void add(TK key, TV val) {
add(key, val, expireSeconds, expireCallback);
} public void add(TK key, TV val, int expireSecondsAfterAccess, Consumer<TV> removeCallback) {
require(key); cache.put(key, new CacheItem(val, expireSecondsAfterAccess, removeCallback));
} public void remove(TK key) {
remove(key, true);
} public void remove(TK key, boolean destroy) {
require(key);
CacheItem remove = cache.remove(key);
if (remove == null) {
return;
} AutoCloseable ac;
if (destroy && (ac = as(remove.value, AutoCloseable.class)) != null) {
try {
ac.close();
} catch (Exception ex) {
Logger.error(ex, "Auto close error");
}
}
} public TV get(TK key) {
require(key); CacheItem item = cache.get(key);
if (item == null) {
return null;
}
item.refresh();
return item.value;
} public TV getOrAdd(TK key, Function<TK, TV> supplier) {
require(key, supplier); CacheItem item = cache.get(key);
if (item == null) {
cache.put(key, item = new CacheItem(supplier.apply(key), expireSeconds, expireCallback));
} else {
item.refresh();
}
return item.value;
}
}
java LRUCache的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Java HashMap的死循环 以及 LRUCache的正确实现
今天RP爆发,16核服务器load飙到30多,cpu使用情况全部99%以上. 从jstack中分析发现全部线程都堵在map.transfer处,如下: "pool-10-thread-23& ...
- 一个最简单的LRUCache实现 (JAVA)
流程图: 1. 代码 import java.util.ArrayList; public class LRUCache { private int cacheMaxSize = 0; private ...
- java LinkedHashMap实现LRUCache缓存
package java_map; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map ...
- Java容器解析系列(17) LruCache详解
在之前讲LinkedHashMap的时候,我们说起可以用来实现LRU(least recent used)算法,接下来我看一下其中的一个具体实现-----android sdk 中的LruCache. ...
- Java集合之LinkedHashMap
一.初识LinkedHashMap 上篇文章讲了HashMap.HashMap是一种非常常见.非常有用的集合,但在多线程情况下使用不当会有线程安全问题. 大多数情况下,只要不涉及线程安全问题,Map基 ...
- LruCache算法原理及实现
LruCache算法原理及实现 LruCache算法原理 LRU为Least Recently Used的缩写,意思也就是近期最少使用算法.LruCache将LinkedHashMap的顺序设置为LR ...
- Java 对象引用方式 —— 强引用、软引用、弱引用和虚引用
Java中负责内存回收的是JVM.通过JVM回收内存,我们不需要像使用C语音开发那样操心内存的使用,但是正因为不用操心内存的时候,也会导致在内存回收方面存在不够灵活的问题.为了解决内存操作不灵活的问题 ...
- LruCache为GridView异步加载大量网络图片
MainActivity如下: import android.os.Bundle; import android.widget.GridView; import android.app.Activit ...
随机推荐
- django项目上线环境部署
django项目上线环境部署 第一步 安装python虚拟环境 1 安装虚拟环境virtualenv 2 安装virtualenvwrapper工具 3 确认virtualenvwrapper.sh脚 ...
- JDK内置工具使用
- 合并K个排序链表(java实现)
题目: 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: ...
- UNDO -- Concept
Undo data Records of the actions of transactions, primarily before they are committed. The database ...
- Inquirer.js
一个使用界面进行交互的命令行集合 4.0以上的版本只支持node 6以上的,node4请使用3.x 目标和理念(hilosophy) 努力去做一个容易的 嵌入式的(embeddable) 和优美的命令 ...
- HATEOAS约束
HATEOAS(Hypermedia as the engine of application state)是 REST 架构风格中最复杂的约束,也是构建成熟 REST 服务的核心.它的重要性在于打破 ...
- 使用layer的弹窗时,出现layer引入成功,触发成功,控制台无报错,但是页面无变化或者仅出现遮罩层的问题的解决思路
------------------------------------------20180410补充------------------------------------------------ ...
- c语言中,在结构体中如何将void *转存为具体需要的数据类型
1. 只需要将该void *类型成员,强制转换为具体的数据类型指针即可.需要注意的是,该强制转换是有风险的,转换时,必须确定void*指向内存实际数据为目标结构体格式,否则可能会出现内存越界访问,从而 ...
- [树组BIT]训练两题重新理解ver.
树状数组重(jiao)新(wo)理(zuo)解(ren) POJ-2352 加加加都给我加 输入是一行一行按照x从小到大给出的,所以对于每个点,要考虑的只是x比它小的点的个数.即记录各个x的情况,并且 ...
- Exception: 'dlib.mmod_rectangle' object has no attribute 'right' - 例外:'dlib.mmod_rectangle'对象没有属性'right'
I'm using dlib for face detection and getting this error Exception: 'dlib.mmod_rectangle' object has ...