Java TimedCache 带时间缓存工具类详解使用

简述

我们在工作中会碰到需要使用带过期时间的缓存场景。但是使用redis有太重了,毕竟缓存的数据很小,放在内存够够的。hutools提供了TimedCache时间缓存工具,可以实现该场景。下面使用到该组件,并为了适配工作场景,对该工具类做优化升级。

Maven依赖

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.6</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1.1-jre</version>
        </dependency>

简单使用

不多说了,上代码。

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.thread.ThreadUtil;

/** @Author huyi @Date 2021/10/12 17:00 @Description: */
public class TimedCacheUtils {
  private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000);

  static {
    /** 每5ms检查一次过期 */
    TIMED_CACHE.schedulePrune(5);
  }

  /**
   * 存入键值对,提供消逝时间
   *
   * @param key
   * @param value
   * @param timeout
   */
  public static void put(String key, String value, Long timeout) {
    /** 设置消逝时间 */
    TIMED_CACHE.put(key, value, timeout);
  }

  /**
   * 每次重新get一次缓存,均会重新刷新消逝时间
   * @param key
   * @return
   */
  public static String get(String key) {
    return TIMED_CACHE.get(key);
  }

  public static void main(String[] args) {
    put("haha", "1", 3000L);
    ThreadUtil.sleep(2000);
    //    if (TIMED_CACHE.containsKey("haha")) {
    //      System.out.println("aa");
    //    }
    System.out.println("第1次结果:" + get("haha"));
    ThreadUtil.sleep(2000);
    System.out.println("第2次结果:" + get("haha"));
    ThreadUtil.sleep(5000);
    System.out.println("第3次结果:" + get("haha"));
    // 取消定时清理
    TIMED_CACHE.cancelPruneSchedule();
  }
}

首先我们看一下执行的效果

说明:

1、设置的超时时间为3000毫秒,所以第一次打印在2秒钟,所以可以获取到值。

2、因为第一次打印调用了get方法,刷新了过期时间,所以依然可以获取到值。

3、第三次打印在5秒后,所以已经过期,无法获取到值,打印null。

那么,需要知道是否缓存还在可以使用containsKey方法。如下:

    put("haha", "1", 3000L);
    ThreadUtil.sleep(2000);
    if (TIMED_CACHE.containsKey("haha")) {
      System.out.println("第1次结果:缓存存在");
    }
//    System.out.println("第1次结果:" + get("haha"));
    ThreadUtil.sleep(2000);
    System.out.println("第2次结果:" + get("haha"));
    ThreadUtil.sleep(5000);
    System.out.println("第3次结果:" + get("haha"));
    // 取消定时清理
    TIMED_CACHE.cancelPruneSchedule();

执行结果如下:

工具优化-监听过期、增加回调

我们在使用TimedCache会发现,一旦缓存过期我们并不能立马知道,很多工作场景中需要对缓存做监听回调。所以我升级了一下该工具类。

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.thread.ThreadUtil;
import com.google.common.util.concurrent.*;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.text.MessageFormat;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

/** @Author huyi @Date 2021/10/12 10:57 @Description: 时间缓存工具 */
public class TimedCacheUtils {
  private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000);
  /** 线程池 */
  private static final ExecutorService executorService = Executors.newCachedThreadPool();

  private static final ListeningExecutorService listeningExecutorService =
      MoreExecutors.listeningDecorator(executorService);
  /** 回调方法映射 */
  private static ConcurrentHashMap<String, Consumer<String>> callbackMap;

  /**
   * 存入键值对,添加过期时间,和消费回调
   *
   * @param key
   * @param timeout
   * @param consumer
   */
  public static void put(String key, String value, Long timeout, Consumer<String> consumer) {
    TIMED_CACHE.put(key, value, timeout);
    addListen(key, consumer);
  }

  /**
   * 获取缓存值
   *
   * @param key
   * @return
   */
  public static String get(String key) {
    return TIMED_CACHE.get(key);
  }

  /**
   * 删除缓存和回调映射
   *
   * @param key
   */
  public static void remove(String key) {
    callbackMap.remove(key);
    TIMED_CACHE.remove(key);
  }

  /**
   * 添加监听器
   *
   * @param key
   * @param consumer
   */
  public static void addListen(String key, Consumer<String> consumer) {
    ListenableFuture<String> listenableFuture =
        listeningExecutorService.submit(
            () -> {
              while (TIMED_CACHE.containsKey(key)) {
                ThreadUtil.sleep(500);
              }
              return key;
            });
    Futures.addCallback(
        listenableFuture,
        new FutureCallback<String>() {
          @Override
          public void onSuccess(@Nullable String s) {
            consumer.accept(s);
          }

          @Override
          public void onFailure(Throwable throwable) {
            throwable.printStackTrace();
          }
        },
        listeningExecutorService);
  }

  public static void main(String[] args) {
    put("haha", "1", 3000L, x -> System.out.println(MessageFormat.format("[{0}] - 缓存消逝", x)));
    ThreadUtil.sleep(2000);
    System.out.println(get("haha"));
    ThreadUtil.sleep(2000);
    System.out.println(get("haha"));
    ThreadUtil.sleep(5000);
    System.out.println(get("haha"));
    // 关闭监听线程池
    listeningExecutorService.shutdown();
  }
}

执行结果:

说明:

1、可以看到监听到缓存过期,并进行了回调。

总结

具体的工具类使用场景,因项目而异,大家看着来。

如果本文对你有帮助,请点个赞支持一下吧。

到此这篇关于Java TimedCache 带时间缓存工具类详解使用的文章就介绍到这了,更多相关Java TimedCache内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java轻松使用工具类实现获取MP3音频时长

    获取mp3格式音频时长. Maven依赖 <dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.1</version> </dependency> 代码 import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.aud

  • Java基础类之ArrayUtils工具类详解

    目录 1.引入pom依赖 2.ArrayUtils中的方法: 3.举例 总结 1.引入pom依赖 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <

  • Java并发工具类Exchanger的相关知识总结

    一.Exchanger的理解 Exchanger 属于java.util.concurrent包: Exchanger 是 JDK 1.5 开始提供的一个用于两个工作线程之间交换数据的封装工具类; 一个线程在完成一定的事务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据. 二.Exchanger类中常用方法 public Exchanger() 无参构造方法.表示创建一个新的交换器. public V exchange(V

  • JAVA文件读取常用工具类(8种)

    目录 一.读取文件成字节 二.将字节写入文件 三.按行读取文件成list 四.输出list到文件 五.从标准输入中读入 六.读取文件成字符串 七.输出字符串到文件 八.读取文件成数据矩阵 总结 JAVA操作文件在经常会使用到,本文汇总了部分JAVA操作文件的读取常用工具类,希望可以帮到大家.直接上代码. 一.读取文件成字节 将文件内容转为字节,需要使用到FileInputStream文件字节输入流,将文件输入到文件字节输入流中,使用FileInputStream的available()方法获取与

  • Java 基础--Arrays工具类详解

    目录 1.数组转换成字符串 2.数组转换成集合 (1)asList (2)stream 流操作 (3)Collections.addAll() 3.对数组进行升序排列 4.判断数组是否相等 5.所有元素赋特定值 6.对数组复制 7.查询数组下标 8.返回数组 hashcode 值 总结 Arrays 是 JDK 提供的操作数组的工具类,Arrays 类提供了动态创建.访问和操作 Java 数组的方法.此类还包含一个允许将数组作为列表来查看的静态工厂. 1.数组转换成字符串 public stat

  • java 如何计算同比增长工具类

    java 计算同比增长工具类 为了数据的严谨性,统一装换为BigDecimal,话不多说,看代码. package com.pig4cloud.pigx.admin.api.util; import java.math.BigDecimal; public class PercentCount { public String percentBigDecimal(BigDecimal preNum,BigDecimal sufNum){ double result = countDecimal(p

  • Java轻松使用工具类实现获取wav时间长度

    获取wav格式音频时长. Maven依赖 <dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.1</version> </dependency> 工具类 import org.jaudiotagger.audio.wav.util.WavInfoReader; import java.io.

  • Java TimedCache 带时间缓存工具类详解使用

    简述 我们在工作中会碰到需要使用带过期时间的缓存场景.但是使用redis有太重了,毕竟缓存的数据很小,放在内存够够的.hutools提供了TimedCache时间缓存工具,可以实现该场景.下面使用到该组件,并为了适配工作场景,对该工具类做优化升级. Maven依赖 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>

  • java金额数字转中文工具类详解

    本文实例为大家分享了java金额数字转中文工具类的具体代码,供大家参考,具体内容如下 java金额数字转中文工具类ConvertNum.java package light.mvc.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * 金额数字转中文工具类 * * @author ardo * */ public class Convert

  • Java项目常见工具类详解

    目录 JWT工具类 MD5工具类 视频点播工具类 公共常量工具类 日期操作工具类 Http客户端工具类 获取IP工具类 JWT工具类 这里一共涉及四个方法: 传入用户信息获得token 传入token字符串判断token是否存在与有效 传入HttpServletRequest,通过获取Header中的token判断是否存在与有效 根据token获取用户id public class JwtUtils { //token过期时间 public static final long EXPIRE =

  • Springboot Mybatis Plus自动生成工具类详解代码

    前言 代码生成器,也叫逆向工程,是根据数据库里的表结构,自动生成对应的实体类.映射文件和接口. 看到很多小伙伴在为数据库生成实体类发愁,现分享给大家,提高开发效率. 一.pom依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> &

  • 微信小程序 常用工具类详解及实例

    微信小程序 常用工具类详解 前言: 做微信小程序当中,会遇到好多的工具类util.js,这里记载下来以便平常使用 (Ps:建议通过目录查看) -获取日期(格式化) function formatTime(date) { var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.getDate() var hour = date.getHours() var minute = date.getMinut

  • js时间戳转yyyy-MM-dd HH-mm-ss工具类详解

    在web开发中,我们经常需要用js将时间戳转yyyy-MM-dd HH-mm-ss类似的格式,这样才适合我们的观感,那么我们该如何在js中将时间戳转换成这种格式呢?其实很简单,我们开发一个时间戳工具类,如下: 第一种:最简单的是一个js时间格式的转换函数方法 function formatDateTime(inputTime) { var date = new Date(inputTime); var y = date.getFullYear(); var m = date.getMonth()

  • python 提取视频中的音频工具类详解

    前言 利用Python的ffmpy库提取视频中的音频.本文提供工具类代码. 环境依赖 需要安装ffmpy,安装指令: pip install ffmpy -i https://pypi.douban.com/simple 工具代码 不废话,上代码. #!/user/bin/env python # coding=utf-8 """ @project : csdn @author : huyi @file : extract_audio_from_audio.py @ide :

  • Android手机管理工具类详解

    Android手机管理工具类 AppPhoneMgr分享给大家,供大家参考,具体内容如下 工具类内的方法: getInstance          : 单例对象 getSDKVersionNumber  : 获取手机系统版本号 getPhoneModel        : 获取手机型号 getPhoneWidth        : 获取手机宽度 getPhoneHeight       : 获取手机高度 getPhoneImei         : 获取手机imei串号 ,GSM手机的 IME

  • java中DateUtils时间工具类详解

    本文实例为大家分享了DateUtils时间工具类的具体代码,供大家参考,具体内容如下 package com.example.administrator.myapp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * Date 工具类 * Created by lychun on 2017/12/07

  • Java FileUploadUtil工具类详解

    本文实例为大家分享了FileUploadUtil工具类的具体代码,供大家参考,具体内容如下 package com.gootrip.util; import java.io.File; import java.util.*; import org.apache.commons.fileupload.*; import javax.servlet.http.HttpServletRequest; import java.util.regex.Pattern; import java.io.IOEx

随机推荐