怎么用Java写一个简单的缓存操作类

发布时间:2021-08-24 21:23:18 作者:chen
来源:亿速云 阅读:208
# 怎么用Java写一个简单的缓存操作类

## 引言

在实际开发中,缓存是提高应用性能的常见手段。通过将频繁访问的数据存储在内存中,可以减少对数据库或外部服务的调用次数。本文将介绍如何用Java实现一个简单的缓存操作类,支持基本的增删改查功能。

---

## 一、缓存的基本概念

### 1.1 什么是缓存
缓存是一种临时存储数据的机制,通常用于:
- 加速数据访问
- 减轻后端压力
- 提升系统响应速度

### 1.2 缓存常见实现方式
- **内存缓存**:基于Java集合类(如`HashMap`)
- **分布式缓存**:如Redis、Memcached
- **本地缓存**:如Guava Cache、Caffeine

本文将聚焦于基于`ConcurrentHashMap`的线程安全内存缓存实现。

---

## 二、核心设计

### 2.1 类结构设计
```java
public class SimpleCache<K, V> {
    private final Map<K, V> cacheMap;
    private final long defaultExpireTime; // 默认过期时间(毫秒)
    
    // 构造方法
    public SimpleCache(long defaultExpireTime) {
        this.cacheMap = new ConcurrentHashMap<>();
        this.defaultExpireTime = defaultExpireTime;
    }
}

2.2 功能需求

  1. 存储键值对
  2. 支持设置过期时间
  3. 线程安全
  4. 提供基本CRUD操作

三、完整实现代码

3.1 基础版本(无过期处理)

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SimpleCache<K, V> {
    private final Map<K, V> cacheMap;
    
    public SimpleCache() {
        this.cacheMap = new ConcurrentHashMap<>();
    }
    
    // 添加/更新缓存
    public void put(K key, V value) {
        cacheMap.put(key, value);
    }
    
    // 获取缓存
    public V get(K key) {
        return cacheMap.get(key);
    }
    
    // 删除缓存
    public void remove(K key) {
        cacheMap.remove(key);
    }
    
    // 清空缓存
    public void clear() {
        cacheMap.clear();
    }
    
    // 获取缓存大小
    public int size() {
        return cacheMap.size();
    }
}

3.2 增强版(带过期时间)

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class ExpirableCache<K, V> {
    private static class CacheEntry<V> {
        V value;
        long expireTime;
        
        CacheEntry(V value, long expireTime) {
            this.value = value;
            this.expireTime = expireTime;
        }
    }

    private final Map<K, CacheEntry<V>> cacheMap;
    private final long defaultExpireTime;

    public ExpirableCache(long defaultExpireTime) {
        this.cacheMap = new ConcurrentHashMap<>();
        this.defaultExpireTime = defaultExpireTime;
    }

    public void put(K key, V value) {
        put(key, value, defaultExpireTime);
    }

    public void put(K key, V value, long expireTime) {
        long expireTimestamp = System.currentTimeMillis() + expireTime;
        cacheMap.put(key, new CacheEntry<>(value, expireTimestamp));
    }

    public V get(K key) {
        CacheEntry<V> entry = cacheMap.get(key);
        if (entry == null) return null;
        
        if (System.currentTimeMillis() > entry.expireTime) {
            cacheMap.remove(key);
            return null;
        }
        return entry.value;
    }

    // 其他方法同上...
}

四、功能测试

4.1 单元测试示例

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class SimpleCacheTest {
    @Test
    void testBasicOperations() {
        SimpleCache<String, String> cache = new SimpleCache<>();
        
        cache.put("key1", "value1");
        assertEquals("value1", cache.get("key1"));
        
        cache.remove("key1");
        assertNull(cache.get("key1"));
    }

    @Test
    void testExpiration() throws InterruptedException {
        ExpirableCache<String, String> cache = new ExpirableCache<>(1000);
        
        cache.put("tempKey", "tempValue");
        assertEquals("tempValue", cache.get("tempKey"));
        
        TimeUnit.MILLISECONDS.sleep(1500);
        assertNull(cache.get("tempKey"));
    }
}

五、优化建议

5.1 定期清理过期缓存

添加定时任务清理过期数据:

private void startCleanerThread() {
    new Thread(() -> {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TimeUnit.SECONDS.sleep(60);
                cacheMap.entrySet().removeIf(entry -> 
                    System.currentTimeMillis() > entry.getValue().expireTime
                );
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }).start();
}

5.2 添加LRU淘汰策略

当缓存达到上限时,移除最近最少使用的数据:

import java.util.LinkedHashMap;
import java.util.Map;

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private final int maxSize;
    
    public LRUCache(int maxSize) {
        super(maxSize, 0.75f, true);
        this.maxSize = maxSize;
    }
    
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > maxSize;
    }
}

六、总结

本文实现了一个具备基本功能的Java缓存类,包含: 1. 线程安全的CRUD操作 2. 过期时间管理 3. 可扩展的优化方案

实际项目中建议考虑: - 使用成熟的缓存库(如Caffeine) - 分布式场景改用Redis - 根据业务需求调整淘汰策略

完整代码已托管至GitHub:示例仓库链接 “`

(注:实际字数约1200字,可根据需要补充更多实现细节或性能优化内容)

推荐阅读:
  1. 用shell写一个简单的告警系统
  2. 用js写的简单轮播特效

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:Java垃圾回收器的定义及算法

下一篇:xgboost的基本原理

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》