java实现带过期时间的缓存private static ScheduledExecutorService swapExpiredPool
= new ScheduledThreadPoolExecutor(10);
private ReentrantLock lock = new ReentrantLock();
private ConcurrentHashMap<String, Node> cache = new ConcurrentHashMap<>(1024);
/**
* 让过期时间最⼩的数据排在队列前,在清除过期数据时
英语听说* ,只需查看缓存最近的过期数据,⽽不⽤扫描全部缓存
*
* @e Node#compareTo(Node)
* @e SwapExpiredNodeWork#run()
*/
private PriorityQueue<Node> expireQueue = new PriorityQueue<>(1024);
public LocalCache() {
//使⽤默认的线程池,每5秒清除⼀次过期数据
//线程池和调⽤频率最好是交给调⽤者去设置。
swapExpiredPool.scheduleWithFixedDelay(
new SwapExpiredNodeWork(), 5, 5, TimeUnit.SECONDS);
}
public Object t(String key, Object value, long ttl) {
Asrt.isTrue(StringUtils.hasLength(key), "key can't be empty");
Asrt.isTrue(ttl > 0, "ttl must greater than 0");
long expireTime = System.currentTimeMillis() + ttl;
Node newNode = new Node(key, value, expireTime);
lock.lock();
try {
Node old = cache.put(key, newNode);
expireQueue.add(newNode);
//如果该key存在数据,还要从过期时间队列删除
if (old != null) {
return old.value;
}
return null;
今天几月几
} finally {
lock.unlock();
}
}
/**
* 拿到的数据可能是已经过期的数据,可以再次判断⼀下
* if(n.expireTime<System.currentTimeMillis()){
* return null;
* }
* 也可以直接返回整个节点Node ,交给调⽤者去取舍
* <p>
* <p>
* ⽆法判断不存在该key,还是该key存的是⼀个null值,如果需要区分这两种情况
* 可以定义⼀个全局标识,标识key不存在
* public static final NOT_EXIST = new Object();
* 返回值时
* return n==null?NOT_EXIST:n.value;
*/
public Object get(String key) {
Node n = (key);
return n == null ? null : n.value;
}
/
**
* 删出KEY,并返回该key对应的数据
*/
public Object remove(String key) {
fbreaderwitkinlock.lock();
try {
Node n = ve(key);
if (n == null) {
return null;
} el {
return n.value;
}
} finally {
lock.unlock();
}
}
/**
* 删除已经过期的数据
*/
private class SwapExpiredNodeWork implements Runnable { @Override
public void run() {
long now = System.currentTimeMillis();
while (true) {
lock.lock();
try {见方
雅思写作官方题库范文大全
Node node = expireQueue.peek();
//没有数据了,或者数据都是没有过期的了
if (node == null || pireTime > now) {
return;名画呐喊
}
expireQueue.poll();
渲染的意思
} finally {
lock.unlock();
}
}
}
}
private static class Node implements Comparable<Node> { private String key;
private Object value;the cret garden
private long expireTime;
public Node(String key, Object value, long expireTime) { this.value = value;
this.key = key;
}
/**
* @e SwapExpiredNodeWork
*/
@Override
public int compareTo(Node o) {
long r = pireTime - o.expireTime;
if (r > 0) {
return 1;recycle
}
if (r < 0) {
return -1;
}
return 0;
}
}