Java内存缓存-通过Google Guava创建缓存

简介: 谷歌Guava缓存Guava介绍Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中。实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问。Guava Cache是单个应用运行时的本地缓存。

谷歌Guava缓存

Guava介绍

Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中。实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问。

image

Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果不符合需求,可以选择Memcached、Redis等工具。

小案例

pom.xml添加guava依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>me.xueyao.cache</groupId>
    <artifactId>java-demo</artifactId>
    <version>1.0.0</version>

    <dependencies>
        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>27.0.1-jre</version>
        </dependency>
    </dependencies>
</project>

GuavaCacheDemo.java 代码如下:

package me.xueyao.cache.java.guava;

import com.google.common.cache.*;
import me.xueyao.cache.java.pojo.User;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author simon
 * https://github.com/google/guava
 */
public class GuavaCacheDemo {
    public static void main(String[] args) throws ExecutionException {
        //缓存接口这里是LoadingCache,LoadingCache在缓存项不存在时可以自动加载缓存
        LoadingCache<String, User> userCache
                //CacheBuilder的构造函数是私有的,只能通过其静态方法newBuilder()来获得CacheBuilder的实例
                = CacheBuilder.newBuilder()
                //设置并发级别为8,并发级别是指可以同时写缓存的线程数
                .concurrencyLevel(8)
                //设置写缓存后8秒钟过期
                .expireAfterWrite(8, TimeUnit.SECONDS)
                //设置写缓存后1秒钟刷新
                .refreshAfterWrite(1, TimeUnit.SECONDS)
                //设置缓存容器的初始容量为5
                .initialCapacity(5)
                //设置缓存最大容量为100,超过100之后就会按照LRU最近虽少使用算法来移除缓存项
                .maximumSize(100)
                //设置要统计缓存的命中率
                .recordStats()
                //设置缓存的移除通知
                .removalListener(new RemovalListener<Object, Object>() {
                    @Override
                    public void onRemoval(RemovalNotification<Object, Object> notification) {
                        System.out.println(notification.getKey() + " 被移除了,原因: " + notification.getCause());
                    }
                })
                //build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
                .build(
                        new CacheLoader<String, User>() {
                            @Override
                            public User load(String key) throws Exception {
                                System.out.println("缓存没有时,从数据库加载" + key);
                                return new User("tony" + key, key);
                            }
                        }
                );

        // 第一次读取
        for (int i = 0; i < 10; i++) {
            User user = userCache.get("uid" + i);
            System.out.println(user);
        }

        // 第二次读取
        for (int i = 0; i < 10; i++) {
            User user = userCache.get("uid" + i);
            System.out.println(user);
        }
        System.out.println("cache stats:");
        //最后打印缓存的命中率等 情况
        System.out.println(userCache.stats().toString());
    }
}

User.java 代码如下:

package me.xueyao.cache.java.pojo;

import java.io.Serializable;

/**
 * @author simon
 */
public class User implements Serializable {
    private String userName;
    private String userId;

    public User(String userName, String userId) {
        this.userName = userName;
        this.userId = userId;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    @Override
    public String toString() {
        return userId + " --- " + userName;
    }
}

运行后的结果如下:

image

第一次循环时缓存中没有数据,构建了缓存,第二次直接命中缓存。如果程序需要单机内存缓存,可以用该方式构建缓存。

相关文章
|
1月前
|
存储 缓存 监控
|
2月前
|
JSON Java 开发工具
Java服务端集成Google FCM推送的注意事项和实际经验
本文分享了作者在公司APP海外发布过程中,选择Google FCM进行消息推送的集成经验。文章详细解析了Java集成FCM推送的多种实现方式,包括HTTP请求和SDK集成,并指出了通知栏消息和透传消息的区别与应用场景。同时,作者还探讨了Firebase项目的创建、配置和服务端集成的注意事项,帮助读者解决文档混乱和选择困难的问题。
69 1
|
2月前
|
存储 缓存 API
LangChain-18 Caching 将回答内容进行缓存 可在内存中或数据库中持久化缓存
LangChain-18 Caching 将回答内容进行缓存 可在内存中或数据库中持久化缓存
44 6
|
2月前
|
JSON Java 开发工具
Java服务端集成Google FCM推送的注意事项和实际经验
公司的app要上海外,涉及到推送功能,经过综合考虑,选择Google FCM进行消息推送。 查看一些集成博客和官方文档,看的似懂非懂,迷迷惑惑。本篇文章除了将我实际集成的经验分享出来,也会对看到的博客及其中产生的疑惑、注意事项一一评论。 从官方文档和众多博客中,你会发现Java集成FCM推送有多种实现方式,会让生产生文档很乱,不知作何选择的困惑。
101 0
|
4月前
|
Java 数据库
震惊!Guava Throwables 类如魔法棒般神奇,让 Java 异常处理华丽变身!
【8月更文挑战第29天】在 Java 开发中,异常处理至关重要,而 Guava 库中的 `Throwables` 类则提供了强大的异常处理工具。它包含了一系列静态方法,如 `propagateIfInstanceOf` 和 `propagateIfPossible`,可以帮助我们有条件地传播异常。此外,`getRootCause` 方法可以深入分析异常的根本原因,有助于快速定位问题所在。无论是构建大型分布式系统还是电商平台,`Throwables` 类都能显著提升异常处理的效率和准确性,使我们的程序更加稳定和可靠。
49 1
|
4月前
|
存储 缓存 监控
Java本地高性能缓存实践问题之Guava Cache被Caffeine所取代的问题如何解决
Java本地高性能缓存实践问题之Guava Cache被Caffeine所取代的问题如何解决
|
4月前
|
缓存 程序员
封装一个给 .NET Framework 用的内存缓存帮助类
封装一个给 .NET Framework 用的内存缓存帮助类
|
4月前
|
缓存 开发框架 .NET
看看 Asp.net core Webapi 项目如何优雅地使用内存缓存
看看 Asp.net core Webapi 项目如何优雅地使用内存缓存
108 1
|
4月前
|
缓存 编解码 测试技术
使用Go实现健壮的内存型缓存
使用Go实现健壮的内存型缓存
72 2
|
4月前
|
SQL 存储 缓存
SQL Server 内存占用较高 - 清除缓存 或 设置内存最大占用值
SQL Server 内存占用较高 - 清除缓存 或 设置内存最大占用值
100 0