You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求支持键值对过期后执行清理操作的哈希映射实现方案

实现带过期后自动清理逻辑的键值映射结构

方案一:基于Guava的RemovalListener实现

Guava的CacheBuilder(替代旧版MapMaker)支持移除监听器,当键值对因过期、手动移除或内存回收被清理时,会触发监听器逻辑,刚好可以用来执行连接关闭操作。

示例代码:

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;

import java.util.concurrent.TimeUnit;

public class ExpiringConnectionCache {
    private final Cache<String, Connection> connectionCache;

    public ExpiringConnectionCache() {
        RemovalListener<String, Connection> removalListener = notification -> {
            Connection conn = notification.getValue();
            if (conn != null && !conn.isClosed()) {
                // 执行连接关闭逻辑
                conn.close();
            }
        };

        connectionCache = CacheBuilder.newBuilder()
                .expireAfterAccess(30, TimeUnit.MINUTES) // 或按写入时间过期expireAfterWrite
                .removalListener(removalListener)
                .build();
    }

    public void putConnection(String key, Connection conn) {
        connectionCache.put(key, conn);
    }

    public Connection getConnection(String key) {
        return connectionCache.getIfPresent(key);
    }
}

方案二:自定义基于ScheduledExecutorService的过期映射

如果不想依赖第三方库,可以自行实现轻量版本,用线程安全的哈希表存储键值对,配合定时任务扫描并清理过期条目。

示例代码:

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class CustomExpiringMap<K, V> {
    private final Map<K, ExpiringEntry<V>> map = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public CustomExpiringMap(long checkInterval, TimeUnit unit) {
        // 定期扫描清理过期条目
        scheduler.scheduleAtFixedRate(this::cleanupExpiredEntries, checkInterval, checkInterval, unit);
    }

    public void put(K key, V value, long expireTime, TimeUnit unit) {
        long expireTimestamp = System.currentTimeMillis() + unit.toMillis(expireTime);
        map.put(key, new ExpiringEntry<>(value, expireTimestamp));
    }

    public V get(K key) {
        ExpiringEntry<V> entry = map.get(key);
        if (entry == null || entry.isExpired()) {
            map.remove(key);
            return null;
        }
        return entry.getValue();
    }

    private void cleanupExpiredEntries() {
        map.entrySet().removeIf(entry -> {
            ExpiringEntry<V> valueEntry = entry.getValue();
            if (valueEntry.isExpired()) {
                // 针对Connection类型执行关闭逻辑
                if (valueEntry.getValue() instanceof Connection) {
                    Connection conn = (Connection) valueEntry.getValue();
                    if (!conn.isClosed()) {
                        conn.close();
                    }
                }
                return true;
            }
            return false;
        });
    }

    private static class ExpiringEntry<V> {
        private final V value;
        private final long expireTimestamp;

        public ExpiringEntry(V value, long expireTimestamp) {
            this.value = value;
            this.expireTimestamp = expireTimestamp;
        }

        public V getValue() {
            return value;
        }

        public boolean isExpired() {
            return System.currentTimeMillis() > expireTimestamp;
        }
    }

    // 关闭定时任务释放资源
    public void shutdown() {
        scheduler.shutdown();
    }
}

方案三:使用Caffeine缓存库

Caffeine是Guava缓存的高性能替代方案,API风格类似但性能更优,同样支持移除监听器处理过期清理逻辑。

示例代码:

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.RemovalListener;

import java.util.concurrent.TimeUnit;

public class CaffeineConnectionCache {
    private final Cache<String, Connection> connectionCache;

    public CaffeineConnectionCache() {
        RemovalListener<String, Connection> removalListener = (key, conn, cause) -> {
            if (conn != null && !conn.isClosed()) {
                conn.close();
            }
        };

        connectionCache = Caffeine.newBuilder()
                .expireAfterWrite(30, TimeUnit.MINUTES)
                .removalListener(removalListener)
                .build();
    }

    public void put(String key, Connection conn) {
        connectionCache.put(key, conn);
    }

    public Connection get(String key) {
        return connectionCache.getIfPresent(key);
    }
}

内容的提问来源于stack exchange,提问作者user9890324

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:09:22