【Java本地缓存详解】

264 阅读3分钟

Java本地缓存详解

引言

在现代的Java应用开发中,本地缓存扮演着重要的角色。它通过将数据暂存于内存中,显著提高了数据访问的速度,减轻了数据库的压力,并增强了系统的响应能力。本文将详细介绍Java本地缓存的使用场景、使用方法,并提供一些流行的本地缓存框架的详解。

使用场景

1. 数据库查询结果缓存

数据库查询是应用中常见的性能瓶颈之一。通过将查询结果缓存在本地,可以避免重复的数据库访问,提高系统的响应速度。

2. 减少网络延迟

对于需要从远程服务获取数据的应用,本地缓存可以减少网络请求的次数,降低网络延迟的影响。

3. 计算密集型结果缓存

对于计算密集型的操作,如数学计算或复杂逻辑处理,将结果缓存可以避免重复计算,提高效率。

4. 会话缓存

在Web应用中,本地缓存可以用来存储用户会话信息,减少会话信息的数据库访问次数。

使用方法

1. 手写本地缓存

封装缓存实体类

首先,我们需要创建一个缓存实体类,用于存储缓存键、缓存值和过期时间。

@Data
public class CacheEntity {
    private String key;
    private Object value;
    private Long expireTime;
}
创建缓存工具类

使用ConcurrentHashMap作为存储结构,并添加缓存管理功能,如添加、删除、查询和清除过期缓存。

public class CacheUtil {
    private final static Map<String, CacheEntity> CACHE_MAP = new ConcurrentHashMap<>();
    private static ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    static {
        executorService.scheduleAtFixedRate(CacheUtil::clear, 1000L, 500L, TimeUnit.MILLISECONDS);
    }
    public static void put(String key, Object value, Long expire) {
        CacheEntity cacheEntity = new CacheEntity();
        cacheEntity.setKey(key);
        cacheEntity.setValue(value);
        if (expire > 0) {
            Long expireTime = System.currentTimeMillis() + Duration.ofSeconds(expire).toMillis();
            cacheEntity.setExpireTime(expireTime);
        }
        CACHE_MAP.put(key, cacheEntity);
    }
    public static Object get(String key) {
        if (CACHE_MAP.containsKey(key)) {
            CacheEntity cacheEntity = CACHE_MAP.get(key);
            if (cacheEntity.getExpireTime() == null || cacheEntity.getExpireTime() > System.currentTimeMillis()) {
                return cacheEntity.getValue();
            }
            CACHE_MAP.remove(key);
        }
        return null;
    }
    public static void remove(String key) {
        CACHE_MAP.remove(key);
    }
    public static void clear() {
        CACHE_MAP.entrySet().removeIf(entry -> entry.getValue().getExpireTime() != null && entry.getValue().getExpireTime() < System.currentTimeMillis());
    }
}

2. Guava Cache

Guava Cache是Google提供的一套完善的JVM本地缓存框架,提供了缓存过期时间设置、缓存容量设置、多种淘汰策略、缓存监控等功能。

引入POM依赖
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>
创建LoadingCache缓存
LoadingCache<Integer, String> cache = CacheBuilder.newBuilder()
        .maximumSize(100)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build(new CacheLoader<Integer, String>() {
            @Override
            public String load(Integer key) throws Exception {
                return "Value for " + key;
            }
        });

3. Caffeine

Caffeine是一个高性能的Java本地缓存库,相比Guava Cache,它提供了更好的性能和更低的内存消耗。

引入POM依赖
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.9.3</version>
</dependency>
开启缓存功能
Cache<Integer, String> cache = Caffeine.newBuilder()
        .maximumSize(10000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();

4. Ehcache

Ehcache是一个功能丰富的开源Java分布式缓存。它提供了丰富的缓存策略和易于使用的API。

引入POM依赖
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.9.7</version>
</dependency>
配置缓存管理器
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
CacheConfiguration<String, String> config = CacheConfigurationBuilder.newCacheConfigurationBuilder(
        String.class, String.class, ResourcePoolsBuilder.heap(10))
        .withExpiry(Expirations.timeToLiveExpiration(Duration.ofMinutes(10)))
        .build();
Cache<String, String> cache = cacheManager.createCache("myCache", config);

总结

Java本地缓存是提高应用性能的重要手段。通过手写缓存或使用成熟的缓存框架如Guava Cache、Caffeine和Ehcache,我们可以有效地减少数据库访问次数,降低网络延迟,并提高系统的响应速度。选择合适的缓存策略和框架对于构建高性能Java应用至关重要。