前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ExpiringMap,一个可以用于缓存的 Map

ExpiringMap,一个可以用于缓存的 Map

作者头像
Demo_Null
发布2020-09-28 14:41:10
2.2K0
发布2020-09-28 14:41:10
举报
文章被收录于专栏:Java 学习Java 学习

1.1 简介

1.1.1 概述

  ExpiringMap 是一个高性能,低开销,零依赖,由线程安全的 ConcurrentMap 实现可以设置过期时间的 Map。功能包括:可设置 Map 中的 Entry 在一段时间后自动过期。可设置 Map 最大容纳值,当到达 Maximum size 后,再次插入值会导致 Map 中的第一个值过期。可添加监听事件,在监听到 Entry 过期时调度监听函数。可以设置懒加载,在调用 get() 方法时创建对象。☛ 项目地址

1.1.2 常用 API

  ♞ enum ExpirationPolicy:枚举,确定 ExpiringMap 元素应如何过期,ACCESSED 根据上次访问的时间使它们过期,即从上次访问后开始计时;CREATED 根据条目的创建时间使它们过期,即从创建之后开始计时。   ♞ enum TimeUnit:枚举,确定时间单位,MILLISECONDS 时间单位毫秒,SECONDS 时间单位秒,MINUTES 时间单位分钟,HOURS 时间单位小时,DAYS 时间单位天   ♞ interface EntryLoader<K, V>:按需加载,内有 V load(K key) 方法,调用时将 key 的新值加载到即将过期的映射中。   ♞ interface ExpiringEntryLoader<K, V>:按需加载,并控制每个值的过期时间(即可变过期时间),内有 ExpiringValue<V> load(K key) 方法,调用时将 key 的新值加载到即将过期的映射中。   ♞ static final class Builder<K, V>:内部类,ExpiringMap 构造器。 默认为 ExpirationPolicy.CREATED,60 个 TimeUnit.SECONDS 到期和 Integer.MAX_VALUE 的 MAXSIZE。   ♞ static Builder<Object, Object> builder():创建一个 ExpiringMap 构造器,返回 ExpiringMap.Builder。   ♞ Builder<K, V> expiration(long duration, TimeUnit timeUnit):构造器中的方法,用于设置 Map 的过期时间,返回 ExpiringMap.Builder。   ♞ Builder<K, V> maxSize(int maxSize):设置 Map 的最大个数,超过限制仍要添加元素时将最先过期的元素过期。   ♞ int getMaxSize():获取 Map 的最大个数。   ♞ Builder<K1, V1> entryLoader(EntryLoader<? super K1, ? super V1> loader):构造器中的方法,可以设置 EntryLoader,EntryLoader 和 ExpiringEntryLoader,不能同时设置。   ♞ Builder<K1, V1> expiringEntryLoader(ExpiringEntryLoader<? super K1, ? super V1> loader):构造器中的方法,可以设置 ExpiringEntryLoader,EntryLoader 和 ExpiringEntryLoader,不能同时设置。   ♞ Builder<K, V> expirationPolicy(ExpirationPolicy expirationPolicy):构造器中的方法,用于设置 Map 的过期策略,返回 ExpiringMap.Builder。   ♞ Builder<K, V> variableExpiration():构造器中的方法,允许 Map 元素具有各自的到期时间,并允许更改到期时间。   ♞ Builder<K1, V1> expirationListener(ExpirationListener<? super K1, ? super V1> listener):构造器中的方法,配置监听每个 Map 元素过期, 通知传入的 ExpirationListener 执行预定好的操作。   ♞ void addExpirationListener(ExpirationListener<K, V> listener):给 ExpiringMap 添加过期监听器。   ♞ void removeExpirationListener(ExpirationListener<K, V> listener):移出 ExpiringMap 的过期监听。   ♞ long getExpiration(K key):获取指定 key 对应的元素的过期时间,返回毫秒值。   ♞ long getExpectedExpiration(K key):获取指定 key 预计到期时间,返货毫秒值。   ♞ ExpirationPolicy getExpirationPolicy(K key):获取指定 key 对应的元素的过期策略。   ♞ interface ExpirationListener<K, V>:过期监听接口,有一个 void expired(K key, V value) 方法,过期时自动调用。   ♞ ExpiringMap<K1, V1> build():创建并返回一个 ExpiringMap。

1.1.3 Maven 依赖

代码语言:javascript
复制
<dependency>
    <groupId>net.jodah</groupId>
    <artifactId>expiringmap</artifactId>
    <version>0.5.8</version>
</dependency>

1.2 示例

1.2.1 设置过期时间与过期协议

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/8/6
 * @description 构建时设置过期时间与过期策略
 */
public class MyTest {

    ExpiringMap<String, String> ACCESSED = ExpiringMap.builder().expiration(10, TimeUnit.SECONDS)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .build();

    ExpiringMap<String, String> CREATED = ExpiringMap.builder().expiration(10, TimeUnit.SECONDS)
            .expirationPolicy(ExpirationPolicy.CREATED)
            .build();

    @Test
    public void testA() throws InterruptedException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ACCESSED.put("name", "小张");
        CREATED.put("name", "小李");
        
        System.out.println(sdf.format(new Date()));
        System.out.println("ACCESSED name 还有 " + ACCESSED.getExpectedExpiration("name")
                + " ms过期, name = " + ACCESSED.get("name"));
        System.out.println("CREATED name 还有 " + CREATED.getExpectedExpiration("name")
                + " ms过期, name = " + CREATED.get("name"));

        Thread.sleep(6000);
        System.out.println(sdf.format(new Date()));
        System.out.println("ACCESSED name 还有 " + ACCESSED.getExpectedExpiration("name")
                + " ms过期, name = " + ACCESSED.get("name"));
        System.out.println("CREATED name 还有 " + CREATED.getExpectedExpiration("name")
                + " ms过期, name = " + CREATED.get("name"));

        Thread.sleep(5000);
        System.out.println(sdf.format(new Date()));
        System.out.println("ACCESSED name 还有 " + ACCESSED.getExpectedExpiration("name")
                + " ms过期, name = " + ACCESSED.get("name"));
        System.out.println("CREATED name 已过期, name = " + CREATED.get("name"));

        Thread.sleep(11000);
        System.out.println(sdf.format(new Date()));
        System.out.println("ACCESSED name 已过期, name = " + ACCESSED.get("name"));
        System.out.println("CREATED name 已过期, name = " + CREATED.get("name"));
    }
}
在这里插入图片描述
在这里插入图片描述

1.2.2 单个元素设置过期时间

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/8/6
 * @description 构建后给单个元素设置过期时间
 */
public class MyTest {

    ExpiringMap<String, String> map = ExpiringMap.builder().variableExpiration().build();

    @Test
    public void testA() throws InterruptedException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("name", "小张", ExpirationPolicy.CREATED, 5000, TimeUnit.MILLISECONDS);

        System.out.println(sdf.format(new Date()));
        System.out.println("还有" + map.getExpectedExpiration("name") + " ms过期 ,name=" + map.get("name"));

        Thread.sleep(5001);
        System.out.println(sdf.format(new Date()));
        System.out.println( "已过期 ,name=" + map.get("name"));
    }
}
在这里插入图片描述
在这里插入图片描述

1.2.3 设置过期监听

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/8/6
 * @description 构建时设置过期监听
 */
public class MyTest {

    ExpiringMap<String, String> map = ExpiringMap.builder().variableExpiration()
                    .expirationListener((thekey, thevalue) -> {
                            System.out.println("key: " + thekey + " -- value: " + thevalue + " 过期");
                    }).build();

    @Test
    public void testA() throws InterruptedException {
        map.put("name", "小张", ExpirationPolicy.CREATED, 5000, TimeUnit.MILLISECONDS);

        Thread.sleep(5001);
        System.out.println( "已过期 ,name=" + map.get("name"));
    }
}
在这里插入图片描述
在这里插入图片描述

1.2.4 添加过期监听

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/8/6
 * @description 构建后添加过期监听
 */
public class MyTest {

    ExpiringMap<String, String> map = ExpiringMap.builder().variableExpiration().build();

	// 可用 Lambda 表达式 (key, value) -> System.out.println()
    ExpirationListener<String, String> expirationListener = new ExpirationListener<String, String>() {
        @Override
        public void expired(String key, String value) {
            System.out.println("key: " + key + " -- value: " + value + " 过期");
        }
    };

    @Test
    public void testA() throws InterruptedException {
        map.put("name", "小张", ExpirationPolicy.CREATED, 5000, TimeUnit.MILLISECONDS);
        map.addExpirationListener(expirationListener);

        Thread.sleep(5001);
        System.out.println( "已过期 ,name=" + map.get("name"));
    }
}
在这里插入图片描述
在这里插入图片描述

1.2.5 懒加载

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/8/6
 * @description 懒加载
 */
public class MyTest {

    ExpiringMap<String, Student> map = ExpiringMap.builder().expiration(5000, TimeUnit.MILLISECONDS)
            .entryLoader(key -> new Student()).build();

    ExpirationListener<String, Student> expirationListener = new ExpirationListener<String, Student>() {
        @Override
        public void expired(String key, Student value) {
            System.out.println("key: " + key + " -- value: " + value + " 过期");
        }
    };

    @Test
    public void testA() throws InterruptedException {
        map.addExpirationListener(expirationListener);
		// 使用懒加载时,可以不用去 put 对象,在调用 get 方法时会自动创建对象
        Student student = map.get("student");
        student.setName("张三");
        student.setAge(23);
        System.out.println(map.get("student"));
        
        Thread.sleep(5001);
    }
}

class Student {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 简介
    • 1.1.1 概述
      • 1.1.2 常用 API
        • 1.1.3 Maven 依赖
        • 1.2 示例
          • 1.2.1 设置过期时间与过期协议
            • 1.2.2 单个元素设置过期时间
              • 1.2.3 设置过期监听
                • 1.2.4 添加过期监听
                  • 1.2.5 懒加载
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档