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 ...
随机推荐
- react+es6+webpack环境搭建以及项目入门
前言:拖了这么久,小菜鸟终于开始正式应用react,和es6来开发项目了.之前超喜欢同学的一个博客风格,这里贴一下地址:https://iwenku.net/,PC端是他很久之前做的,最近他重新做了一 ...
- Hadoop之运行模式
Hadoop运行模式包括:本地模式.伪分布式以及完全分布式模式. 一.本地运行模式 1.官方Grep案例 1)在hadoop-2.7.2目录下创建一个 input 文件夹 [hadoop@hadoop ...
- Creed_颓知乎
题目背景 二轮省选前的一个最后周,Creed_还在颓知乎. 突然,她看到一个有趣的回答. 紧接着,Creed_点开了评论区,又看到了一个有趣的评论. Creed_想了一下,发现自己并不会,于是她又顺着 ...
- 解决:SSM框架中普通类调用Service的问题 (转)
http://blog.csdn.net/gwd1154978352/article/details/73480959
- 非阻塞模式(ioctlsocket)
//Server.cpp #include <stdio.h> #include <winsock2.h> //winsock.h (2种套接字版本) #pragma comm ...
- vmware12启动centos6.8报错ACPI:memory_hp:Memory online failed
报错信息 打开后出现黑屏上只显示 ACPI:memory_hp:Memory online failed for 0x10000000 - 0x80000000 BUG: soft lockup - ...
- Visual Studio 向工程中添加文件夹
将要添加的文件夹拷贝到工程的目标文件夹中. 打开工程,在Solution Explorer中选中“Show All Files”按钮. 然后VS会显示文件夹中包含,但是不在工程中的文件夹. 右键该文件 ...
- 静态代码扫描之阿里java代码规范IDEA插件
前言 2017年2月9日,首次公布<阿里巴巴Java开发手册>; 2017年9月25日,阿里巴巴集团发布了<阿里巴巴Java开发手册>PDF终极版; 2017年10月14日,在 ...
- 【密码技术】Part 4 SSL/TLS
01 SSL/TLS基本概念 02 TLS协议流程图
- 【基础】使用cookies,实现免登陆(七)
实现过程: 1.测试网站:www.dx.com 2.登陆后的cookies:"DXSSO","Token=20A0FA7D-XXXX-XXXX-XXXX".至于 ...