基于Java的简单缓存系统设计

基于Java实现的简单缓存系统设计方案

在日常开发中,为了提升系统性能和减少对数据库的频繁访问,我们会设计和使用缓存系统。在本文中,将介绍一个使用Java设计简单缓存系统的解决方案。

功能描述

该缓存系统旨在实现以下主要功能:

  1. 基本缓存操作:提供数据的读取、写入和删除方法。
  2. 缓存超时清理:支持缓存存储的过期时间,超过时间后自动清除。
  3. 线程安全:支持多线程环境下的安全操作。
  4. 扩展性强:方便后续开发中增加更多功能,如存储持久化等。

解决方案设计

  1. 设计基本结构 我们创建一个SimpleCache类,该类内部维护一个ConcurrentHashMap来实现缓存存储,key 为缓存的键,value 为包含实际数据和过期时间戳的包装对象。并提供常用的增删查操作。

  2. 缓存存储对象 属性包括实际的缓存数据和过期时间戳。我们使用以下简单的数据结构:

    public class CacheObject<T> {
        private T value;             // 缓存的值
        private long expireAt;       // 缓存过期时间戳
    
        public CacheObject(T value, long expireAt) {
            this.value = value;
            this.expireAt = expireAt;
        }
    
        public T getValue() { return value; }
        public long getExpireAt() { return expireAt; }
    }
    
  3. 核心类实现 下面是SimpleCache的实现代码:

    import java.util.concurrent.*;
    import java.util.*;
    
    public class SimpleCache<K, V> {
        private final ConcurrentHashMap<K, CacheObject<V>> cacheMap = new ConcurrentHashMap<>();
        private final ScheduledExecutorService cleaner = Executors.newSingleThreadScheduledExecutor();
    
        public SimpleCache() {
            // 定期清除过期缓存
            cleaner.scheduleAtFixedRate(this::cleanUp, 10, 10, TimeUnit.SECONDS);
        }
    
        // 添加缓存
        public void put(K key, V value, long expireInMillis) {
            long expireAt = System.currentTimeMillis() + expireInMillis;
            cacheMap.put(key, new CacheObject<>(value, expireAt));
        }
    
        // 获取缓存
        public V get(K key) {
            CacheObject<V> cacheObject = cacheMap.get(key);
            if (cacheObject == null) return null;
    
            // 检查是否过期
            if (cacheObject.getExpireAt() > System.currentTimeMillis()) {
                return cacheObject.getValue();
            } else {
                cacheMap.remove(key); // 过期则清理
                return null;
            }
        }
    
        // 删除缓存
        public void remove(K key) {
            cacheMap.remove(key);
        }
    
        // 清理过期缓存
        private void cleanUp() {
            long currentTime = System.currentTimeMillis();
            Iterator<Map.Entry<K, CacheObject<V>>> iterator = cacheMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<K, CacheObject<V>> entry = iterator.next();
                if (entry.getValue().getExpireAt() <= currentTime) {
                    iterator.remove();
                }
            }
        }
    
        public void shutdown() {
            cleaner.shutdown();
        }
    }
    
  4. 使用示例

    public class CacheExample {
        public static void main(String[] args) throws InterruptedException {
            SimpleCache<String, String> cache = new SimpleCache<>();
    
            cache.put("key1", "value1", 5000); // 缓存有效期为5秒
    
            System.out.println("key1: " + cache.get("key1")); // 输出 key1: value1
            Thread.sleep(6000);
            System.out.println("key1 after 6 seconds: " + cache.get("key1")); // 输出 null
    
            cache.shutdown();
        }
    }
    

优化与扩展

  1. 动态删除优化:对于清除过期缓存,可以根据应用需求扩展为即将被访问的 key 在访问时进行检查和清理,减少定时清理的性能消耗。
  2. 持久化支持:支持将缓存内容保存到外部存储设备,比如文件或数据库中,以便在应用重启后快速恢复。
  3. 分布式缓存:结合 Redis 或其他分布式缓存工具,扩展为支持分布式环境的缓存系统。

通过本文的简单示例实现,可以满足基本的缓存需求,并能作为复杂缓存系统的基础框架进行扩展。