Hutool Hutool
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
  • 快速入门

  • 核心(hutool-core)

    • AI(Hutool-ai)

    • 注解(annotation)

    • 数组(array)

    • JavaBean(bean)

    • 缓存(cache)

    • 类加载器(classloader)

    • 编码解码(codec)

    • 集合(collection)

    • 比较器(comparator)

    • 压缩(compress)

    • 类型转换(convert)

    • 数据(data)

    • 日期时间(date)

    • 异常(exception)

    • 函数(func)

    • IO流(io)

    • 语言特性(lang)

    • Map(map)

      • 简介
      • MapUtil
      • MapBuilder
      • MapJoiner
      • MapGetUtil
      • CaseInsensitiveMap
      • CamelCaseMap
      • BiMap
      • FixedLinkedHashMap
      • ForestMap
      • Dict
      • MultiValueMap
      • ListValueMap
      • SetValueMap
      • Table
      • SoftConcurrentMap
        • 功能介绍
        • 主要特性
        • 适用场景
        • 使用示例
          • 示例1:基本用法
          • 示例2:使用Loader自动加载
          • 示例3:遍历和清理
          • 示例4:使用自定义引用队列
        • 注意事项
        • 方法列表
      • WeakConcurrentMap
      • WeakKeyConcurrentMap
      • ConcurrentLinkedHashMap
    • 数字数学(math)

    • 网络(net)

    • 对象池(pool)

    • 反射(reflect)

    • 正则(regex)

    • 服务提供(spi)

    • 聚合操作(stream)

    • 字符串文本(text)

    • 并发和线程(thread)

    • 树结构(tree)

    • 工具集合(util)

    • XML操作(xml)

  • 定时任务(hutool-cron)

  • 加密(hutool-crypto)

  • 数据库(hutool-db)

  • 扩展(hutool-extra)

  • HTTP(hutool-http)

  • 日志(hutool-log)

  • 配置文件(hutool-setting)

  • JSON(hutool-json)

  • Office办公(hutool-poi)

  • 套接字(hutool-socket)

  • GUI(hutool-swing)

  • 指南
  • 核心(hutool-core)
  • Map(map)
Hutool
2026-01-19
目录

SoftConcurrentMap

# 功能介绍

SoftConcurrentMap是Hutool中提供的基于软引用的并发Map实现,它结合了ConcurrentHashMap的并发安全特性和软引用的自动回收机制。当内存不足时,JVM会自动回收软引用对象,从而释放内存,这使得SoftConcurrentMap非常适合用作缓存,尤其是缓存那些占用内存较大但可以重新创建的对象。

# 主要特性

  • 基于软引用实现,内存不足时自动回收对象
  • 并发安全,支持多线程操作
  • 基于ConcurrentHashMap实现,性能优异
  • 支持所有Map接口方法
  • 支持null值,但不支持null键
  • 支持自动清理过期条目
  • 支持获取值时的自动加载(通过实现Loader接口)
  • 线程安全,适合多线程环境使用
  • 支持自定义引用队列和清理策略

# 适用场景

  1. 实现内存敏感的缓存系统
  2. 缓存占用内存较大的对象
  3. 实现LRU(最近最少使用)缓存的替代方案
  4. 需要自动管理内存的缓存场景
  5. 多线程环境下的缓存需求
  6. 缓存可以重新创建的对象
  7. 任何需要自动内存管理的Map场景

# 使用示例

# 示例1:基本用法

// 创建SoftConcurrentMap实例
SoftConcurrentMap<String, byte[]> softMap = new SoftConcurrentMap<>();

// 添加大对象到缓存
byte[] largeObject1 = new byte[1024 * 1024]; // 1MB
byte[] largeObject2 = new byte[1024 * 1024]; // 1MB
byte[] largeObject3 = new byte[1024 * 1024]; // 1MB

softMap.put("key1", largeObject1);
softMap.put("key2", largeObject2);
softMap.put("key3", largeObject3);

// 获取对象
byte[] retrieved1 = softMap.get("key1");
// 输出: [B@... (1MB byte数组)

// 当内存不足时,JVM会自动回收软引用对象
// 再次获取时,如果对象已被回收,会返回null
byte[] retrieved2 = softMap.get("key2");
// 可能输出: [B@... 或 null(取决于内存情况)

# 示例2:使用Loader自动加载

// 创建SoftConcurrentMap实例,使用Loader自动加载值
SoftConcurrentMap<String, String> softMap = new SoftConcurrentMap<>((key) -> {
    // 模拟从数据库或其他数据源加载数据
    Console.log("Loading data for key: " + key);
    return "Loaded value for " + key;
});

// 获取值,如果不存在则自动加载
String value1 = softMap.get("key1");
// 输出: Loading data for key: key1
// 输出: Loaded value for key1

// 再次获取,直接从缓存获取(如果未被回收)
String value2 = softMap.get("key1");
// 输出: Loaded value for key1(直接从缓存获取,不会再次加载)

// 当内存不足时,对象被回收后,再次获取会重新加载
String value3 = softMap.get("key1");
// 可能输出: Loading data for key: key1
// 可能输出: Loaded value for key1(如果对象已被回收,会重新加载)

# 示例3:遍历和清理

// 创建SoftConcurrentMap实例
SoftConcurrentMap<String, String> softMap = new SoftConcurrentMap<>();
softMap.put("key1", "value1");
softMap.put("key2", "value2");
softMap.put("key3", "value3");

// 遍历Map
softMap.forEach((key, value) -> {
    Console.log(key + "=" + value);
});
// 输出:
// key1=value1
// key2=value2
// key3=value3

// 手动清理已回收的条目
softMap.cleanUp();

// 获取Map大小
int size = softMap.size();
// 输出: 3(如果没有对象被回收)

// 清空Map
softMap.clear();

# 示例4:使用自定义引用队列

// 创建引用队列
ReferenceQueue<String> queue = new ReferenceQueue<>();

// 创建SoftConcurrentMap实例,使用自定义引用队列
SoftConcurrentMap<String, String> softMap = new SoftConcurrentMap<>(queue);

// 添加键值对
softMap.put("key1", "value1");
softMap.put("key2", "value2");

// 手动触发垃圾回收(仅用于测试,实际使用中不需要)
System.gc();

// 处理引用队列中的回收对象
Reference<? extends String> ref;
while ((ref = queue.poll()) != null) {
    // 处理回收的引用
    Console.log("Object recycled: " + ref);
}

# 注意事项

  1. SoftConcurrentMap是线程安全的,适合多线程环境使用
  2. 基于软引用实现,内存不足时对象会被自动回收
  3. 不支持null键,但支持null值
  4. 性能与ConcurrentHashMap相当,适合大多数场景
  5. 使用Loader接口可以实现自动加载功能,类似于Guava Cache
  6. 建议定期调用cleanUp()方法清理已回收的条目,避免内存泄漏
  7. 软引用对象的回收时机取决于JVM的内存情况,无法精确控制
  8. 适合缓存可以重新创建的对象,不适合缓存无法重新创建的对象
  9. 可以通过构造函数自定义引用队列和Loader

# 方法列表

SoftConcurrentMap实现了ConcurrentMap接口,因此支持所有Map接口方法,主要包括:

方法名 描述 参数 返回值
SoftConcurrentMap() 创建默认的SoftConcurrentMap 无 无
SoftConcurrentMap(ReferenceQueue queue) 使用自定义引用队列创建SoftConcurrentMap queue: 引用队列 无
SoftConcurrentMap(Loader<K, V> loader) 使用Loader创建SoftConcurrentMap,支持自动加载 loader: 加载器 无
SoftConcurrentMap(Loader<K, V> loader, ReferenceQueue queue) 使用Loader和引用队列创建SoftConcurrentMap loader: 加载器, queue: 引用队列 无
put(K key, V value) 添加键值对,值使用软引用包装 key: 键, value: 值 V
get(Object key) 获取值,如果值已被回收且设置了Loader,则自动加载 key: 键 V
remove(Object key) 移除键值对 key: 键 V
clear() 清空所有键值对 无 void
size() 获取Map大小(包括已回收但未清理的条目) 无 int
cleanUp() 清理已回收的条目 无 int
containsKey(Object key) 判断是否包含指定键 key: 键 boolean
containsValue(Object value) 判断是否包含指定值 value: 值 boolean
keySet() 获取所有键的集合 无 Set
values() 获取所有值的集合(包括已回收的值,返回null) 无 Collection
entrySet() 获取所有键值对的集合 无 Set<Map.Entry<K, V>>
forEach(BiConsumer<? super K, ? super V> action) 遍历所有键值对 action: 遍历操作 void
replace(K key, V oldValue, V newValue) 替换键值对(并发安全) key: 键, oldValue: 旧值, newValue: 新值 boolean
putIfAbsent(K key, V value) 如果键不存在则添加键值对(并发安全) key: 键, value: 值 V
Table
WeakConcurrentMap

← Table WeakConcurrentMap→

Theme by Vdoing | Copyright © 2025-2026 Hutool | Apache-2.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式