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

Guava Cache达到maximumSize时如何执行自定义逻辑而非移除旧元素?

解决Guava Cache实现连接限制时的自定义拦截逻辑问题

要实现缓存达到上限时拦截新连接(而非自动移除旧元素),核心是不要依赖Guava Cache的自动驱逐机制,而是手动控制元素添加逻辑,在添加前判断当前连接数是否已达上限。以下是具体实现方案:

方案思路

  1. 放弃maximumSize的自动驱逐,改用原子计数器精确追踪当前连接数
  2. 结合Guava Cache的removalListener,在元素过期或被移除时自动递减计数器,保证计数准确性
  3. 在处理新连接时,先尝试递增计数器,若超过上限则执行拦截逻辑,否则将玩家加入缓存

代码实现

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

// 初始化计数器与缓存
AtomicInteger currentConnectionCount = new AtomicInteger(0);
Cache<String, Player> connectionCache = CacheBuilder.newBuilder()
        .expireAfterWrite(1, TimeUnit.SECONDS)
        .removalListener((RemovalListener<String, Player>) notification -> {
            // 元素过期/被移除时,计数器减一
            currentConnectionCount.decrementAndGet();
        })
        .build();

// 处理玩家连接的核心方法
public boolean handlePlayerConnection(Player player) {
    String playerId = player.getId();
    int maxConnections = instance.getSettings().getInt("CONNECTION-PER-SEC");

    // 尝试递增连接计数
    int newCount = currentConnectionCount.incrementAndGet();
    if (newCount > maxConnections) {
        // 超过上限,回滚计数并执行拦截
        currentConnectionCount.decrementAndGet();
        player.disconnect("连接过于频繁,请稍后再试");
        return false;
    }

    // 检查玩家是否已在缓存中(避免重复连接导致计数错误)
    if (connectionCache.getIfPresent(playerId) != null) {
        currentConnectionCount.decrementAndGet();
        return true; // 允许重复连接,或根据需求调整逻辑
    }

    // 将玩家加入缓存
    connectionCache.put(playerId, player);
    return true;
}

关键说明

  • 原子计数器AtomicInteger保证了并发场景下计数的准确性,避免多线程竞争导致的计数错误
  • removalListener会在缓存元素因过期或手动移除时触发,确保计数器与缓存实际元素数同步
  • 不再使用maximumSize,避免Guava自动驱逐旧元素,完全由我们控制连接数上限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:55:42