ExpiringMap(支持过期的Map)的使用方法

时间:2025-04-28 08:19:48

前言:

最近公司的服务调用系统,需要把放进Redis中的一部分数据,直接放进内存中进行取读。这样,可以加快取读速度并且还可以减配Redis集群的服务器配置。一开始,我打算有手写一个带过期的Map。但是,自我感觉技术菜鸟,手写可能想不周全,更容易出问题。所以我在网络上寻找一番,找到了ExpiringMap这个开源架包。简单看了一下ExpiringMap的文档,应该可以支持业务改造。下面,我介绍一下ExpiringMap的使用。

正文:

一、ExpiringMap简介:

它具有高性能、低开销、零依赖、线程安全、使用ConcurrentMa的实现过期entries等优点。主要特点包括:过期策略、可变有效期、最大尺寸、侦听器过期、延迟输入加载、过期自省。

二、项目地址:

GitHub - jhalterman/expiringmap: A high performance thread-safe map that expires entries

三、使用:

0.引入架包依赖:

<dependency>
    <groupId></groupId>
    <artifactId>expiringmap</artifactId>
    <version>0.5.9</version>
</dependency>

1.简单使用,设置5秒的过期时间:

    /**
     * 简单使用,设置5秒的过期时间
     * 
     * @throws InterruptedException
     */
    private static void test1() throws InterruptedException {
        ExpiringMap<String, String> map = ()
                // 设置过期时间和过期时间单位
                .expiration(5, )
                .build();
        ("1", "测试");
        ("2", "测试");
        (6000);
        (map); // {}
    }

 2.过期策略的使用(CREATED、ACCESSED):

   /**
     * 过期策略的使用:
     * CREATED:  在每次更新元素时,过期倒计时清零
     * ACCESSED: 在每次访问元素时,过期倒计时清零
     *
     * @throws InterruptedException
     */
    private static void test2() throws InterruptedException {

        // 使用默认的CREATED策略:
        ("----使用默认的CREATED策略:----");
        ExpiringMap<String, String> map = ()
                .expirationPolicy()
                .expiration(2, )
                .build();
        // -- 测试CREATED策略,访问的情况
        ("1", "测试");
        (1000);
        (("1"));  // 测试
        (1001);
        (("1"));  // null
        // -- 测试CREATED策略,更新的情况
        ("2","测试");
        (1000);
        (("2")); // 测试
        ("2","测试1");
        (1000);
        (("2")); // 测试1
        (900);
        (("2")); // 测试1
        (200);
        (("2")); // null


        // 使用默认的ACCESSED策略:
        ("----使用默认的ACCESSED策略:----");
        ExpiringMap<String, String> map1 = ()
                .expirationPolicy()
                .expiration(2, )
                .build();
        // -- 测试ACCESSED策略,访问的情况
        ("1", "测试");
        (1000);
        (("1"));  // 测试
        (1100);
        (("1"));  // 测试
        (2100);
        (("1"));  // null
        
        // 只是访问时,过期倒计时清零
        ("2","测试");
        (1000);
        (map1); // {2=测试}
        (1100);
        (map1); // {}
    }

3.可变有效期,即单独为每个entity设置过期时间和策略:

    /**
     * 可变有效期,即单独为每个entity设置过期时间和策略:
     *
     * @throws InterruptedException
     */
    private static void test3() throws InterruptedException {
        ExpiringMap<String, String> map = ()
                .variableExpiration()
                .expiration(2, )
                .build();
        ("1", "测试", , 1, );
        ("2", "测试", , 2, );
        ("3", "测试", , 999, );
        ("4", "测试", , 1003, );
        (1002);
        (map); // {2=测试, 4=测试}
    }

4.最大值的使用:

   /**
     * 最大值的使用:
     * Map中映射数目超过最大值的大小时,先过期第一个要过期的entity过期
     *
     * @throws InterruptedException
     */
    private static void test4() throws InterruptedException {
        ExpiringMap<String, String> map = ()
                .maxSize(3)
                .expiration(2, )
                .build();
        ("1", "测试");
        ("2", "测试");
        ("3", "测试");
        (map); // {1=测试, 2=测试, 3=测试}
        ("4", "测试");
        (map); // {2=测试, 3=测试, 4=测试}
        
    }

5. 过期侦听器的使用:

    /**
     * 过期侦听器的使用:当entity过期时,可以通知过期侦听器:
     *
     * @throws InterruptedException
     */
    private static void test5() throws InterruptedException {
        ExpiringMap<String, String> map = ()
                // 同步过期提醒
                .expirationListener((key, value) -> remindExpiration(key, value))
                // 异步过期提醒
                .asyncExpirationListener((key, value) -> remindAsyncExpiration(key, value))
                .expiration(2, )
                .build();
        ("1", "测试");
        while (true){

        }

    }

    /**
     * 过期提醒
     *
     * @param key
     * @param value
     */
    private static void remindExpiration(Object key, Object value) {
        ("过期提醒,key: " + key + " value: " + value);
    }

    /**
     * 异步过期提醒
     *
     * @param key
     * @param value
     */
    private static void remindAsyncExpiration(Object key, Object value) {
        ("异步过期提醒,key: " + key + " value: " + value);
    }

6.懒加载的使用:

    /**
     * 懒加载的使用:put方法时不创建对象,在调用get方法时自动去创建对象
     *
     * @throws InterruptedException
     */
    private static void test6() throws InterruptedException {
        ExpiringMap<String, Student> map = ()
                .expiration(2, )
                .entryLoader(name -> new Student(name))
                .build();
        (map); // {}
        ("hanxiaozhang");
        (map); // {hanxiaozhang=$Student@5d6f64b1}
    }

7. 其他:

   /**
     * 其他:
     *
     * @throws InterruptedException
     */
    private static void test7() throws InterruptedException {
        ExpiringMap<String, String> map = ()
                .expiration(2, )
                .build();
        ("1", "测试");
        // 查看剩余过期时间:
        long remainExpiration = ("1");
        ("查看剩余过期时间:" + remainExpiration);  // 查看剩余过期时间:1970
        // 查看设置过期时间:
        long setExpiration = ("1");
        ("查看设置过期时间:" + setExpiration);  // 查看设置过期时间:2000
        // 重置过期时间
        ("1");
        ("查看剩余过期时间:" + ("1")); // 查看剩余过期时间:1999

    }