创建一个自定义的缓存类,包含一个ConcurrentHashMap来存储缓存数据,以及一个ScheduledExecutorService来执行定时清理任务,它接受一个cleanupInterval参数,表示清理间隔。:
import java.util.concurrent.*;
public class CustomCache {
private final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private final long cleanupInterval; // 清理间隔,单位:毫秒
public CustomCache(long cleanupInterval) {
this.cleanupInterval = cleanupInterval;
startCleanupTask();
}
public Object get(String key) {
return cache.get(key);
}
public void put(String key, Object value) {
cache.put(key, value);
}
public void remove(String key) {
cache.remove(key);
}
private void startCleanupTask() {
executorService.scheduleAtFixedRate(() -> {
System.out.println("Performing cache cleanup...");
// 在这里实现清理缓存的逻辑,例如根据过期时间移除缓存项
// cache.entrySet().removeIf(entry -> entry.getValue() instanceof ExpiringValue && ((ExpiringValue) entry.getValue()).isExpired());
// 示例:移除所有缓存项(仅用于演示)
cache.clear();
}, cleanupInterval, cleanupInterval, TimeUnit.MILLISECONDS); // }, 60000, 60000);
}
public void shutdown() {
executorService.shutdown();
}
}
方法2:
import java.util.concurrent.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public class LRUCacheWithCleanup<K, V> {
private final int capacity;
private final ConcurrentHashMap<K, CacheEntry<V>> cacheMap;
private final Queue<K> accessQueue;
private final long cleanupInterval; // 清理间隔时间,单位为毫秒
private final ScheduledExecutorService cleanupService;
private static class CacheEntry<V> {
V value;
long accessTime;
CacheEntry(V value, long accessTime) {
this.value = value;
this.accessTime = accessTime;
}
}
public LRUCacheWithCleanup(int capacity, long cleanupInterval) {
this.capacity = capacity;
this.cacheMap = new ConcurrentHashMap<>();
this.accessQueue = new ConcurrentLinkedQueue<>();
this.cleanupInterval = cleanupInterval;
this.cleanupService = Executors.newSingleThreadScheduledExecutor();
scheduleCleanupTask(); // 安排定时清理任务
}
private void scheduleCleanupTask() {
// 安排定时任务,周期性地清理过期的缓存项
cleanupService.scheduleAtFixedRate(this::cleanupCache, cleanupInterval, cleanupInterval, TimeUnit.MILLISECONDS);
}
private void cleanupCache() {
// 清理过期的缓存项
long currentTime = System.currentTimeMillis();
Iterator<K> iterator = accessQueue.iterator();
while (iterator.hasNext()) {
K key = iterator.next();
CacheEntry<V> entry = cacheMap.get(key);
// 如果缓存项不存在或已过期,则从缓存和访问队列中移除
if (entry == null || currentTime - entry.accessTime > cleanupInterval) {
iterator.remove();
if (entry != null) {
cacheMap.remove(key);
}
}
}
}
public V get(K key) {
// 根据键获取缓存项
CacheEntry<V> entry = cacheMap.get(key);
if (entry == null) {
return null;
}
// 更新访问时间并将该项移动到访问队列的末尾
entry.accessTime = System.currentTimeMillis();
accessQueue.remove(key);
accessQueue.add(key);
return entry.value;
}
public void put(K key, V value) {
// 将键值对放入缓存
CacheEntry<V> newEntry = new CacheEntry<>(value, System.currentTimeMillis());
CacheEntry<V> oldEntry = cacheMap.put(key, newEntry);
if (oldEntry != null) {
// 键已存在,更新访问时间并重新排序
accessQueue.remove(key);
} else {
// 键不存在,检查是否需要从缓存中移除最老的项
if (cacheMap.size() > capacity) {
K oldestKey = accessQueue.poll();
if (oldestKey != null) {
cacheMap.remove(oldestKey);
}
}
}
// 将新项添加到访问队列的末尾
accessQueue.add(key);
}
public V remove(K key) {
// 从缓存中移除指定的键
CacheEntry<V> entry = cacheMap.remove(key);
if (entry != null) {
accessQueue.remove(key);
}
return entry == null ? null : entry.value;
}
public void shutdown() {
// 关闭清理服务
cleanupService.shutdown();
try {
if (!cleanupService.awaitTermination(60, TimeUnit.SECONDS)) {
cleanupService.shutdownNow();
}
} catch (InterruptedException e) {
cleanupService.shutdownNow();
}
}
}