ExpiringMap用法详解

1、功能简介

  • 可设置Map中的Entry在一段时间后自动过期。
  • 可设置Map最大容纳值,当到达Maximum size后,再次插入值会导致Map中的第一个值过期。
  • 可添加监听事件,在监听到Entry过期时调度监听函数。
  • 可以设置懒加载,在调用get()方法时创建对象。

2、依赖

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

3、详细使用介绍

import net.jodah.expiringmap.ExpirationListener;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author JHL
 * @version 1.0
 * @date 2023/6/15 14:08
 * @since : JDK 11
 */
public class T {
    public static void main(String[] args) {
        // test1();
        // test2();
        // test3();
        // test4();
        // test5();
        // test6();
        // test7();
        // test8();
        while (true) {

        }
    }

    /**
     * 创建key就开始对key存在的时长计时,过期则去除这个key
     * 过期策略:ExpirationPolicy.CREATED
     */
    private static void test1() {
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .expiration(5000, TimeUnit.MILLISECONDS)
                .expirationPolicy(ExpirationPolicy.CREATED)
                .build();

        map.put("key", "value");

        try {
            System.out.println(map.get("key"));                 // value

            Thread.sleep(2000);
            System.out.println("######################### \t[ 经过2秒 ]\t #########################");
            System.out.println(map.get("key"));                 // value

            System.out.println("######################### \t[ 经过5秒 ]\t #########################");
            Thread.sleep(3000);
            System.out.println(map.get("key"));                 // 此时已过期 null

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 对指定key的value进行更新后将对此key重新计时
     * put()、replace()为更新key的操作
     * 过期策略:ExpirationPolicy.CREATED
     */
    private static void test2() {
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .expiration(5000, TimeUnit.MILLISECONDS)
                .expirationPolicy(ExpirationPolicy.CREATED)
                .build();

        map.put("key1", "value1");
        map.put("key2", "value2");

        try {
            System.out.println(map.get("key1"));        // value1
            System.out.println(map.get("key2"));        // value2

            Thread.sleep(4000);
            System.out.println("######################### \t[ 经过4秒,并且更新key1 ]\t #########################");
            // map.put("key1", "123");
            map.replace("key1", "123");
            System.out.println(map.get("key1"));        // 123
            System.out.println(map.get("key2"));       // value2

            Thread.sleep(1000);
            System.out.println("######################### \t[ 经过5秒 ]\t #########################");
            System.out.println(map.get("key1"));        // 123
            System.out.println(map.get("key2"));        // null

            Thread.sleep(3500);
            System.out.println("######################### \t[ 经过9.5秒 ]\t #########################");
            System.out.println(map.get("key1"));        // 123
            System.out.println(map.get("key2"));        // null

            Thread.sleep(500);
            System.out.println("######################### \t[ 经过10秒 ]\t #########################");
            System.out.println(map.get("key1"));        // null
            System.out.println(map.get("key2"));        // null

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 在每次访问指定key,则该key的过期时间会重置。
     * 过期策略:ExpirationPolicy.ACCESSED
     */
    private static void test3() {
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .expiration(5000, TimeUnit.MILLISECONDS)
                .expirationPolicy(ExpirationPolicy.ACCESSED)
                .build();

        map.put("key", "value");

        try {
            System.out.println(map.get("key"));                 // value

            Thread.sleep(4000);
            System.out.println("######################### \t[ 经过4秒 ]\t #########################");
            System.out.println(map.get("key"));                 // value

            Thread.sleep(4000);
            System.out.println("######################### \t[ 经过8秒 ]\t #########################");
            System.out.println(map.get("key"));                 // value

            Thread.sleep(4000);
            System.out.println("######################### \t[ 经过12秒 ]\t #########################");
            System.out.println(map.get("key"));                 // value

            Thread.sleep(5001);
            System.out.println("######################### \t[ 经过17秒 ]\t #########################");
            System.out.println(map.get("key"));                 // null
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 添加新key时指定过期时长与过期策略
     */
    private static void test4() {
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .variableExpiration()
                .expirationPolicy(ExpirationPolicy.CREATED)
                .build();

        map.put("key1", "value1", ExpirationPolicy.ACCESSED, 5000, TimeUnit.MILLISECONDS);
        map.put("key2", "value2", 10000, TimeUnit.MILLISECONDS);

        try {
            Thread.sleep(2000);
            System.out.println("######################### \t[ 2秒后 ]\t #########################");
            System.out.println(map.get("key1"));                    // value1
            System.out.println(map.get("key2"));                    // value2

            Thread.sleep(4999);
            // Thread.sleep(5001);
            System.out.println("######################### \t[ 7秒后 ]\t #########################");
            System.out.println(map.get("key1"));                    // null
            System.out.println(map.get("key2"));                    // value2

            Thread.sleep(3000);
            System.out.println("######################### \t[ 10秒后 ]\t #########################");
            System.out.println(map.get("key1"));                    // null
            System.out.println("key2:" + map.get("key2"));          // null
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 超map的最大容量时,移除最老的key
     */
    private static void test5() {
        // 设置最大容量为10;
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .maxSize(10)
                .build();

        int size = 10;
        System.out.println("######################### \t[ 添加10个key ]\t #########################");
        for (int i = 0; i < size; i++) {
            map.put("key" + i, "value" + i);
        }

        System.out.println("######################### \t[ 打印10个key的值 ]\t #########################");
        for (int i = 0; i < size; i++) {
            System.out.println(map.get("key" + i));
        }

        System.out.println("######################### \t[ 在加10个AAA ]\t #########################");
        for (int i = 0; i < size; i++) {
            map.put("AAA" + i, "a" + i);
        }

        System.out.println("######################### \t[ 打印10个key ]\t #########################");
        for (int i = 0; i < 10; i++) {
            System.out.println(map.get("key" + i));
        }
        System.out.println("######################### \t[ 打印10个AAA ]\t #########################");
        for (int i = 0; i < 10; i++) {
            System.out.println(map.get("AAA" + i));
        }
    }

    /**
     * 过期回调,指定存活时长的key在经过限制时长后过期,回调某个方法
     * 不指定过期策略时,默认使用:ExpirationPolicy.CREATED
     */
    private static void test6() {
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .variableExpiration()
                .expirationListener((k, v) -> System.out.println("过期了:" + k))
                .build();

        map.put("key", "value", 5000, TimeUnit.MILLISECONDS);

        try {
            Thread.sleep(2000);
            System.out.println(map.get("key"));         // value
            Thread.sleep(2800);
            System.out.println(map.get("key"));         // value
            Thread.sleep(200);
            System.out.println(map.get("key"));         // null
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 在运行时动态 添加/删除 过期事件监听器
     */
    private static void test7() {
        ExpiringMap<String, String> map = ExpiringMap
                .builder()
                .variableExpiration()
                .build();

        ExpirationListener<String, String> expirationListener = ((key, value) -> System.out.println("过期事件" + "key:" + key + " value:" + value));

        try {
            // 1、先添加key
            map.put("key", "value", ExpirationPolicy.CREATED, 5000, TimeUnit.MILLISECONDS);

            // 2、在添加监听
            Thread.sleep(1000);
            System.out.println("######################### \t[ 1秒后 ]\t #########################");
            map.addExpirationListener(expirationListener);

            // 3、等待key过期
            System.out.println("######################### \t[ 5秒后 ]\t #########################");
            Thread.sleep(4001);

            // 4、清除监听
            map.removeExpirationListener(expirationListener);

            map.put("key2", "value2", ExpirationPolicy.CREATED, 2000, TimeUnit.MILLISECONDS);
            Thread.sleep(2001);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用懒加载模式,不用主动向map中put对象,在调用get方法时自动去创建对象。
     */
    private static void test8() {
        Map<String, Connection> map = ExpiringMap
                .builder().expiration(5000, TimeUnit.MILLISECONDS)
                .expirationListener((key, value) -> System.out.println("过期:" + key))
                .entryLoader(ip -> new Connection((String) ip))
                .build();

        try {

            System.out.println(map.get("127.0.0.1"));
            System.out.println(map.get("127.0.0.2"));
            System.out.println(map.get("127.0.0.3"));
            System.out.println(map.get("127.0.0.4"));

            Thread.sleep(5010);

            System.out.println("######################### \t[ 执行结束 ]\t #########################");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    static class Connection {
        String ip;

        public Connection(String ip) {
            this.ip = ip;
        }

        @Override
        public String toString() {
            return "Connection{" + "ip='" + ip + '\'' + '}';
        }
    }
}
posted @ 2021-10-12 16:12  黄河大道东  阅读(339)  评论(0编辑  收藏  举报