java中的本地缓存GuavaCache使用方法和示例教程

 更新时间:2025年07月19日 10:41:44   作者:呀哈哈kk  
GuavaCache是Google提供的高效本地缓存工具,支持线程安全、自动加载、过期策略及内存回收,适用于高并发场景,可提升系统性能,减少数据库访问压力

在现代互联网应用中,高并发场景是每个开发者都可能遇到的挑战。为了提高系统的响应速度和吞吐量,缓存技术成为了一个不可或缺的部分。Google Guava库提供了一个强大的本地缓存实现——GuavaCache,它不仅简单易用,而且性能优秀,非常适合处理高并发场景。

 GuavaCache简介

GuavaCache是Google Guava库中的一个组件,用于实现内存中的缓存。它支持多种配置选项,如设置缓存大小、过期策略等,并且提供了线程安全的操作方法,使得在多线程环境中使用更加方便。

主要特性

线程安全

GuavaCache的所有操作都是线程安全的,这使得它在高并发环境下能够稳定运行,无需额外的同步控制。

自动加载

可以通过LoadingCache接口实现数据的自动加载,当缓存中没有找到对应的键时,会自动调用指定的方法来加载数据。

过期策略

支持基于时间的过期策略,包括创建后过期(expire after write)和访问后过期(expire after access)。

内存回收

GuavaCache可以根据内存情况自动回收不常用的条目,避免内存溢出。

使用示例

基本使用

首先,需要添加Guava库到项目中,如果使用Maven,可以在pom.xml中添加如下依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

接下来,创建一个简单的缓存实例:

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

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

public class GuavaCacheExample {
    public static void main(String[] args) throws ExecutionException {
        // 创建一个LoadingCache实例
        LoadingCache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(100) // 设置缓存的最大容量
                .expireAfterWrite(10, TimeUnit.MINUTES) // 设置过期时间为10分钟
                .build(new CacheLoader<String, String>() { // 定义默认的数据加载机制
                    @Override
                    public String load(String key) throws Exception {
                        return "value-" + key;
                    }
                });

        // 访问缓存
        String value = cache.get("key1");
        System.out.println(value); // 输出: value-key1
    }
}

异常处理

在实际应用中,数据加载可能会抛出异常。GuavaCache允许你定义如何处理这些异常:

try {
    String value = cache.get("key2");
} catch (ExecutionException e) {
    // 处理异常
    System.err.println("Failed to load value for key2: " + e.getCause());
}

手动加载和删除

除了自动加载外,还可以手动将数据放入缓存或从缓存中删除数据:

// 手动加载
cache.put("key3", "value3");

// 手动删除
cache.invalidate("key3");

性能优化

并发级别

通过设置concurrencyLevel参数可以调整缓存的并发性能,这个值表示预计同时访问缓存的线程数。通常情况下,默认值已经足够好,但在特定场景下适当调整可以提升性能。

软引用与弱引用

对于内存敏感的应用,可以考虑使用软引用或弱引用来存储缓存项,这样当系统内存不足时,JVM会自动回收这些对象。

CacheBuilder.newBuilder()
    .softValues() // 使用软引用
    .weakKeys() // 使用弱引用
    .build();

GuavaCache是一个强大而灵活的缓存工具,特别适合于需要高性能和低延迟的应用。通过合理配置,可以有效应对高并发场景下的各种挑战。这篇文章介绍了GuavaCache的基本概念、主要特性和使用方法,以及一些性能优化的技巧,适合对缓存技术感兴趣的开发者阅读。Guava Cache 是一个非常高效的本地缓存库,特别适合处理高并发场景。下面是一个使用 Guava Cache 的示例代码,假设我们有一个需要频繁查询用户信息的应用场景。

场景描述

假设我们有一个用户服务,需要频繁地从数据库中查询用户信息。为了减少数据库的访问压力,我们可以使用 Guava Cache 来缓存用户信息。

依赖引入

首先,确保你的项目中已经引入了 Guava 库。如果你使用的是 Maven,可以在 pom.xml 中添加以下依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

示例代码

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

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

public class UserCacheService {

    // 创建一个 Guava Cache 实例
    private final Cache<String, User> userCache;

    public UserCacheService() {
        // 配置缓存
        this.userCache = CacheBuilder.newBuilder()
                .maximumSize(1000) // 最大缓存条目数
                .expireAfterWrite(10, TimeUnit.MINUTES) // 缓存条目在写入后 10 分钟过期
                .recordStats() // 记录缓存统计信息
                .build();
    }

    // 获取用户信息
    public User getUser(String userId) {
        try {
            return userCache.get(userId, () -> loadUserFromDatabase(userId));
        } catch (ExecutionException e) {
            throw new RuntimeException("Failed to load user from cache", e);
        }
    }

    // 从数据库加载用户信息
    private User loadUserFromDatabase(String userId) {
        // 模拟从数据库加载用户信息
        System.out.println("Loading user " + userId + " from database");
        return new User(userId, "User Name " + userId);
    }

    public static void main(String[] args) {
        UserCacheService service = new UserCacheService();

        // 模拟高并发请求
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                User user = service.getUser("12345");
                System.out.println("User: " + user);
            }).start();
        }
    }
}

class User {
    private String id;
    private String name;

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{id='" + id + "', name='" + name + "'}";
    }
}

代码解释

  1. 缓存配置
  • maximumSize(1000):设置缓存的最大条目数为 1000。
  • expireAfterWrite(10, TimeUnit.MINUTES):设置缓存条目在写入后 10 分钟过期。
  • recordStats():记录缓存的统计信息,方便监控和调试。
  1. 获取用户信息
  • getUser 方法通过 userCache.get 方法从缓存中获取用户信息。如果缓存中没有该用户信息,则调用 loadUserFromDatabase 方法从数据库中加载用户信息,并将其存入缓存。
  1. 从数据库加载用户信息
  • loadUserFromDatabase 方法模拟从数据库中加载用户信息的过程。
  1. 模拟高并发请求
  • main 方法中,创建多个线程模拟高并发请求,每个线程都尝试获取同一个用户的用户信息。由于缓存的存在,多次请求只会触发一次数据库查询。

备注

1. 基本概念

  • Cache:Guava Cache的主要接口,用于定义缓存的基本操作,如获取、插入和删除缓存项。
  • LoadingCache:继承自Cache,提供了一种自动加载数据到缓存中的机制,当缓存中没有请求的数据时,可以自动从数据源加载。
  • RemovalListener:监听器接口,用于监听缓存项的移除事件,可以实现一些清理工作或日志记录。

2. 创建Guava Cache

创建一个简单的GuavaCache可以通过CacheBuilder来完成。以下是一个基本的例子:

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.util.concurrent.TimeUnit;

public class GuavaCacheExample {
    public static void main(String[] args) {
        // 创建一个最大容量为100,超过容量后使用LRU算法移除最近最少使用的条目,
        // 并且设置10分钟后过期的缓存
        Cache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .removalListener(notification -> System.out.println("Removed: " + notification.getKey()))
                .build();

        // 向缓存中添加数据
        cache.put("key1", "value1");

        // 从缓存中获取数据
        String value = cache.getIfPresent("key1");
        System.out.println(value); // 输出: value1
    }
}

3. 使用LoadingCache

LoadingCache可以在缓存未命中时自动加载数据,这通常通过实现CacheLoader来完成:

import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

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

public class LoadingCacheExample {
    public static void main(String[] args) throws ExecutionException {
        LoadingCache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .build(new CacheLoader<String, String>() {
                    @Override
                    public String load(String key) throws Exception {
                        return fetchFromDatabase(key);
                    }
                });

        // 获取数据,如果缓存中没有,会自动调用load方法加载
        String value = cache.get("key1");
        System.out.println(value); // 输出: 从数据库获取的数据
    }

    private static String fetchFromDatabase(String key) {
        // 模拟从数据库查询
        return "从数据库获取的数据";
    }
}

4. 高级特性

  • 统计信息:通过cache.stats()可以获得缓存的统计信息,如命中率、加载失败次数等。
  • 异步加载:可以使用getUncheckedgetAll方法进行异步加载,适合于耗时较长的操作。
  • 刷新策略:通过refreshAfterWrite方法可以设置缓存项在写入后的多久时间后刷新。

5. 注意事项

  • 线程安全:Guava Cache是线程安全的,多线程环境下的读写操作不需要额外的同步控制。
  • 内存占用:虽然Guava Cache提供了多种策略来控制缓存大小,但在高并发场景下仍需注意内存使用情况,避免因内存溢出导致应用崩溃。
  • 过期策略:合理设置过期时间和清除策略,避免缓存中的数据长时间不更新,导致数据陈旧。

总结

通过使用 Guava Cache,我们可以有效地减少对数据库的访问次数,提高系统的性能和响应速度。特别是在高并发场景下,缓存的作用更加明显。希望这个示例对你有所帮助!在处理高并发场景时,缓存是提高系统性能和响应速度的重要手段之一。Google Guava库提供了一个非常强大的本地缓存实现——GuavaCache,它不仅提供了基本的缓存功能,还支持多种高级特性,如过期策略、大小限制、统计信息等,非常适合在高并发环境下使用。

到此这篇关于java中的本地缓存GuavaCache使用方法和示例教程的文章就介绍到这了,更多相关java本地缓存GuavaCache内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java用20行代码实现抖音小视频批量转换为gif动态图

    Java用20行代码实现抖音小视频批量转换为gif动态图

    这篇文章主要介绍了Java用20行代码实现抖音小视频批量转换为gif动态图,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 微信支付H5调用支付详解(java版)

    微信支付H5调用支付详解(java版)

    本篇文章主要介绍了微信支付H5调用支付详解,小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧。
    2016-12-12
  • java导出pdf文件的详细实现方法

    java导出pdf文件的详细实现方法

    这篇文章主要介绍了java导出pdf文件的详细实现方法,包括制作模板、获取中文字体文件、实现后端服务以及前端发起请求并生成下载链接,需要的朋友可以参考下
    2025-03-03
  • 阿里云发布 Spring Boot 新脚手架工程

    阿里云发布 Spring Boot 新脚手架工程

    这篇文章主要介绍了阿里云发布 Spring Boot 新脚手架的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,可以参考下
    2020-04-04
  • 面试总结:秒杀设计、AQS 、synchronized相关问题

    面试总结:秒杀设计、AQS 、synchronized相关问题

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧
    2021-06-06
  • ArrayList和JSONArray边遍历边删除到底该如何做

    ArrayList和JSONArray边遍历边删除到底该如何做

    这篇文章主要介绍了ArrayList和JSONArray边遍历边删除到底该如何做,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • SpringBoot内部外部配置文件加载顺序解析

    SpringBoot内部外部配置文件加载顺序解析

    这篇文章主要介绍了SpringBoot内部外部配置文件加载顺序解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java中ByteBuddy动态字节码操作库的使用技术指南

    Java中ByteBuddy动态字节码操作库的使用技术指南

    ByteBuddy 是一个功能强大的 Java 字节码操作库,可以帮助开发者在运行时动态生成和修改类,而无需直接接触复杂的 ASM API,本文给大家介绍了Java ByteBuddy动态字节码操作库的使用技术指南,需要的朋友可以参考下
    2025-04-04
  • springboot security之前后端分离配置方式

    springboot security之前后端分离配置方式

    这篇文章主要介绍了springboot security之前后端分离配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • java中申请不定长度数组ArrayList的方法

    java中申请不定长度数组ArrayList的方法

    今天小编就为大家分享一篇java中申请不定长度数组ArrayList的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07

最新评论