MENU

ExpiringMap学习笔记

December 1, 2023 • 技术阅读设置

前言

最近在做些比较奇葩的项目,架构组要求建设场景时不允许有任何形式的数据存储,一切数据均要存在各支撑组件中,但在实际业务中难免会有需要部分数据需要缓存的情况,如缓存调用第三方API的token信息等,我就在想有没有一种可以支持设定过期时间的map工具,搜索后发现了ExpiringMap。

ExpiringMap

高性能、低开销、线程安全、一款基于内存可过期的 Map,支持自动删除过期的 Key-Value 对, 项目地址戳这里

主要特点:

  1. 支持基于时间的键过期。
  2. 支持基于访问时间的键过期。
  3. 支持基于Map容纳值大小的键过期。
  4. 支持添加监听事件,在监听到元素过期时调度监听函数。
  5. 支持设置懒加载,在调用get()方法时创建对象。
  6. 线程安全。
  7. 开源 Apache 2.0。

依赖

<dependency>
    <groupId>net.jodah</groupId>
    <artifactId>expiringmap</artifactId>
    <version>0.5.10</version>
</dependency>

示例

Map容纳值大小的键过期

/**
 * description: 构建时设置Map容纳值大小
 * date: 2023/12/1 12:40
 * author: LenonJin
 */
public static void exMapTest() throws InterruptedException {
    // 构建
    ExpiringMap<String, Object> exMap = ExpiringMap.builder()
            .maxSize(2)
            .build();

    // 测试
    exMap.put("key-1", "第一把钥匙");
    exMap.put("key-2", "第二把钥匙");
    log.info("exMap-> {}", JSONUtil.toJsonStr(exMap));

    exMap.put("key-3", "第三把钥匙");
    log.info("exMap-> {}", JSONUtil.toJsonStr(exMap));
}

执行结果
17:13:47.462 [main] INFO com.example.practise.ExMapTest - exMap-> {"key-1":"第一把钥匙","key-2":"第二把钥匙"}
17:13:47.466 [main] INFO com.example.practise.ExMapTest - exMap-> {"key-2":"第二把钥匙","key-3":"第三把钥匙"}

.maxSize: 设置Map的大小,当达到MaxSize后,再次插入会导致Map中的第一个元素过期。

过期时间及过期策略

/**
 * description: 构建时设置过期时间及过期策略
 * date: 2023/12/1 10:19
 * author: LenonJin
 */
public static void exMapTest2() throws InterruptedException {
    // 构建
    ExpiringMap<String, Object> exMap = ExpiringMap.builder()
            .expiration(5, TimeUnit.SECONDS)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .build();

    // 测试
    exMap.put("token", "5277d026-23a9-42da-96d5-a236ec644870");

    log.info(Objects.nonNull(exMap.get("token")) ? "过期时间-> " + exMap.getExpectedExpiration("token") + " ms" : "已过期");
    Thread.sleep(6000);
    log.info(Objects.nonNull(exMap.get("token")) ? "过期时间-> " + exMap.getExpectedExpiration("token") + " ms" : "已过期");
}

执行结果
17:14:35.955 [main] INFO com.example.practise.ExMapTest - 过期时间-> 4999 ms
17:14:41.968 [main] INFO com.example.practise.ExMapTest - 已过期

.expiration: 设置过期时间,时间单位有 秒、分、时、天。
.expirationPolicy: 设置过期策略,共有两种,ExpirationPolicy.CREATED在put及replace操作时重置过期时间。
ExpirationPolicy.ACCESSED在get操作时重置过期时间。

单个元素过期时间及策略

/**
 * description: 构建后给单个元素设置过期时间及过期策略
 * date: 2023/12/1 12:19
 * author: LenonJin
 */
public static void exMapTest3() throws InterruptedException {
    // 构建
    ExpiringMap<String, Object> exMap = ExpiringMap.builder()
            .expiration(5, TimeUnit.SECONDS)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .variableExpiration()
            .build();

    // 测试
    exMap.put("token", "5277d026-23a9-42da-96d5-a236ec644870", ExpirationPolicy.CREATED, 10, TimeUnit.SECONDS);

    log.info(Objects.nonNull(exMap.get("token")) ? "过期时间-> " + exMap.getExpectedExpiration("token") + " ms" : "已过期");
    Thread.sleep(6000);
    log.info(Objects.nonNull(exMap.get("token")) ? "过期时间-> " + exMap.getExpectedExpiration("token") + " ms" : "已过期");
}

执行结果
17:16:05.370 [main] INFO com.example.practise.ExMapTest - 过期时间-> 9996 ms
17:16:11.387 [main] INFO com.example.practise.ExMapTest - 过期时间-> 3978 ms

.variableExpiration() 设置Map允许单个元素有各自的到期时间及过期策略。

过期监听

/**
 * description: 构建时设置过期监听
 * date: 2023/12/1 12:54
 * author: LenonJin
 */
public static void exMapTest4() throws InterruptedException {
    // 构建
    ExpiringMap<String, Object> exMap = ExpiringMap.builder()
            .expiration(5, TimeUnit.SECONDS)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .expirationListener((key, value) -> {
                log.info("监听到token过期->{}", value);
            })
            .build();

    // 测试
    exMap.put("token", "5277d026-23a9-42da-96d5-a236ec644870");

    log.info(Objects.nonNull(exMap.get("token")) ? "过期时间-> " + exMap.getExpectedExpiration("token") + " ms" : "已过期");
    Thread.sleep(6000);
    log.info(Objects.nonNull(exMap.get("token")) ? "过期时间-> " + exMap.getExpectedExpiration("token") + " ms" : "已过期");
}

执行结果
17:16:57.749 [main] INFO com.example.practise.ExMapTest - 过期时间-> 4999 ms
17:17:02.749 [ExpiringMap-Expirer] INFO com.example.practise.ExMapTest - 监听到token过期->5277d026-23a9-42da-96d5-a236ec644870
17:17:03.760 [main] INFO com.example.practise.ExMapTest - 已过期

.expirationListener() 设置监听Map中的每个元素,当元素过期时执行预定操作。

懒加载

/**
 * description: 构建时设置懒加载
 * date: 2023/12/1 13:54
 * author: LenonJin
 */
public static void exMapTest5() throws InterruptedException {
    // 构建
    ExpiringMap<String, JSONObject> exMap = ExpiringMap.builder()
            .expiration(5, TimeUnit.SECONDS)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .entryLoader(key -> new JSONObject())
            .build();

    // 测试
    log.info("exMap-> {}", JSONUtil.toJsonStr(exMap));

    JSONObject objA = exMap.get("key-1");
    objA.set("name", "第一次GET");
    log.info("exMap-> {}", JSONUtil.toJsonStr(exMap));

    JSONObject objB = exMap.get("key-2");
    objB.set("name", "第二次GET");
    log.info("exMap-> {}", JSONUtil.toJsonStr(exMap));
}

执行结果
17:18:11.845 [main] INFO com.example.practise.ExMapTest - exMap-> {}
17:18:11.878 [main] INFO com.example.practise.ExMapTest - exMap-> {"key-1":{"name":"第一次GET"}}
17:18:11.879 [main] INFO com.example.practise.ExMapTest - exMap-> {"key-1":{"name":"第一次GET"},"key-2":{"name":"第二次GET"}}

.entryLoader() 设置Map懒加载,使用时不需再先进行put操作,直接get时会自动创建对象。

Last Modified: December 6, 2023
Leave a Comment

10 Comments
  1. 想想你的文章写的特别好https://www.237fa.com/

  2. 不错不错,我喜欢看 www.jiwenlaw.com

  3. 真棒!

  4. 《二楼传来的歌声》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/62431.html

  5. 《我的双面爱人》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/18245.html

  6. 《火速救兵2》韩国剧高清在线免费观看:https://www.jgz518.com/xingkong/26668.html

  7. 《二楼传来的歌声》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/62431.html

  8. 《阿卡普高第二季》海外剧高清在线免费观看:https://www.jgz518.com/xingkong/98328.html

  9. 《邪恶花园》恐怖片高清在线免费观看:https://www.jgz518.com/xingkong/106217.html

  10. 哈哈哈,写的太好了https://www.lawjida.com/