# metona-cache-mini-pro
**Repository Path**: thzxx/metona-cache-mini-pro
## Basic Information
- **Project Name**: metona-cache-mini-pro
- **Description**: 一个轻量级的Java内存缓存实现,无第三方依赖,基于JDK 17开发。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: https://gitee.com/thzxx/maven/tree/master/cn/metona/metona-cache-mini-pro
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-08-21
- **Last Updated**: 2025-08-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Metona Cache Mini Pro 1.1.0
一个轻量级的Java内存缓存实现,无第三方依赖,基于JDK 17开发。
## 特性
- **多种淘汰策略**: LRU、LFU、FIFO
- **TTL过期机制**: 支持设置缓存项过期时间
- **线程安全**: 完全线程安全的实现
- **统计信息**: 提供详细的缓存使用统计
- **自动清理**: 定期清理过期缓存项
- **零依赖**: 不依赖任何第三方库
- **异步加载**: 支持异步加载缓存值 (1.1.0新增)
- **批量操作**: 支持批量put/get/remove操作 (1.1.0新增)
- **事件监听**: 支持缓存事件监听 (1.1.0新增)
- **序列化支持**: 支持缓存数据的序列化/反序列化 (1.1.0新增)
- **缓存分片**: 支持分片缓存提高并发性能 (1.1.0新增)
- **缓存模板**: 提供通用缓存模板类 (1.1.0新增)
## 快速开始
### Maven依赖
```xml
cn.metona
metona-cache-mini-pro
1.1.0
```
### 基本使用
```java
/// 创建默认配置的缓存
MetonaCache cache = new MetonaCache<>();
// 放入缓存项
cache.put("key1", "value1");
cache.put("key2", "value2", 60000); // 60秒过期
// 获取缓存项
String value = cache.get("key1");
// 检查是否存在
boolean exists = cache.containsKey("key1");
// 移除缓存项
String removedValue = cache.remove("key1");
// 获取统计信息
CacheStats stats = cache.getStats();
System.out.println(stats);
// 关闭缓存
cache.close();
```
### 异步加载
```java
MetonaCache cache = new MetonaCache<>();
// 异步获取
CompletableFuture future = cache.getAsync("key", key ->
CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "async loaded value";
})
);
String result = future.get(); // 阻塞获取结果
```
### 批量操作
```java
MetonaCache cache = new MetonaCache<>();
// 批量放入
Map data = Map.of(
"key1", "value1",
"key2", "value2",
"key3", "value3"
);
BatchOperationResult result = cache.putAll(data);
// 批量获取
Set keys = Set.of("key1", "key2", "key3");
Map values = cache.getAll(keys);
// 批量删除
BatchOperationResult removeResult = cache.removeAll(keys);
```
### 事件监听
```java
MetonaCache cache = new MetonaCache<>();
// 添加监听器
cache.addListener(event -> {
System.out.println("Cache event: " + event.getEventType() +
" key: " + event.getKey() +
" value: " + event.getValue());
});
cache.put("test", "value"); // 会触发PUT事件
```
### 缓存分片
```java
CacheConfig config = CacheConfig.custom().setMaxSize(1000);
ShardedCache shardedCache = new ShardedCache<>(4, config);
shardedCache.put("key1", "value1");
String value = shardedCache.get("key1");
```
### 缓存模板
```java
CacheTemplate template = new CacheTemplate<>();
// 使用模板操作
template.put("key1", "value1");
String value = template.get("key1");
// 缓存预热
Map warmupData = Map.of("key1", "value1", "key2", "value2");
template.warmUp(warmupData);
```
### 自定义配置
```java
CacheConfig config = CacheConfig.custom()
.setMaxSize(2000)
.setDefaultTtlMillis(30 * 60 * 1000) // 30分钟
.setEvictionPolicy(CacheEvictionPolicy.LFU)
.setEnableStats(true);
MetonaCache cache = new MetonaCache<>(config);
```
## API说明
### 主要方法
- `put(K key, V value)`: 放入缓存项(使用默认TTL)
- `put(K key, V value, long ttlMillis)`: 放入缓存项(指定TTL)
- `get(K key)`: 获取缓存项
- `get(K key, Function loader)`: 获取缓存项,不存在时自动加载
- `getAsync(K key, AsyncCacheLoader loader)`: 异步获取缓存项
- `containsKey(K key)`: 检查键是否存在
- `remove(K key)`: 移除缓存项
- `clear()`: 清空缓存
- `size()`: 获取缓存大小
- `keySet()`: 获取所有键
- `putAll(Map map)`: 批量放入
- `getAll(Set keys)`: 批量获取
- `removeAll(Set keys)`: 批量删除
- `getStats()`: 获取统计信息
- `addListener(CacheListener listener)`: 添加监听器
- `close()`: 关闭缓存
### 配置选项
- `maxSize`: 最大缓存容量
- `defaultTtlMillis`: 默认过期时间(毫秒)
- `evictionPolicy`: 淘汰策略(LRU/LFU/FIFO)
- `enableStats`: 是否启用统计
- `cleanupIntervalMillis`: 清理间隔时间
## 使用示例
创建一个测试类来验证功能:
### TestCacheV1_1_0.java
```java
package cn.metona.cache.test;
import cn.metona.cache.CacheConfig;
import cn.metona.cache.CacheEvictionPolicy;
import cn.metona.cache.MetonaCache;
import cn.metona.cache.async.AsyncCacheLoader;
import cn.metona.cache.batch.BatchOperationResult;
import cn.metona.cache.event.CacheEvent;
import cn.metona.cache.event.CacheEventType;
import cn.metona.cache.event.CacheListener;
import cn.metona.cache.shard.ShardedCache;
import cn.metona.cache.template.CacheTemplate;
import cn.metona.cache.utils.TimeUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestCacheV1_1_0 {
public static void main(String[] args) throws Exception {
System.out.println("=== Metona Cache 1.1.0 测试 ===\n");
testBasicOperations();
testAsyncOperations();
testBatchOperations();
testEventListener();
testShardedCache();
testCacheTemplate();
System.out.println("所有测试完成!");
}
private static void testBasicOperations() {
System.out.println("1. 基本操作测试");
MetonaCache cache = new MetonaCache<>();
cache.put("name", "Metona Cache");
cache.put("version", "1.1.0", TimeUtils.secondsToMillis(2));
System.out.println(" name: " + cache.get("name"));
System.out.println(" version: " + cache.get("version"));
System.out.println(" 缓存大小: " + cache.size());
try {
Thread.sleep(2100);
System.out.println(" 过期后version: " + cache.get("version"));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
cache.close();
System.out.println();
}
private static void testAsyncOperations() throws Exception {
System.out.println("2. 异步操作测试");
MetonaCache cache = new MetonaCache<>();
AsyncCacheLoader loader = key ->
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(500); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "async value for " + key;
});
long start = System.currentTimeMillis();
CompletableFuture future = cache.getAsync("asyncKey", loader);
String result = future.get(); // 阻塞等待结果
long end = System.currentTimeMillis();
System.out.println(" 异步加载结果: " + result);
System.out.println(" 加载耗时: " + (end - start) + "ms");
System.out.println(" 缓存中获取: " + cache.get("asyncKey"));
cache.close();
System.out.println();
}
private static void testBatchOperations() {
System.out.println("3. 批量操作测试");
MetonaCache cache = new MetonaCache<>();
// 批量放入
Map data = new HashMap<>();
data.put("batch1", "value1");
data.put("batch2", "value2");
data.put("batch3", "value3");
BatchOperationResult putResult = cache.putAll(data);
System.out.println(" 批量放入成功: " + putResult.getSuccessful().size());
System.out.println(" 批量放入失败: " + putResult.getFailed().size());
// 批量获取
Set keys = Stream.of("batch1", "batch2", "batch3", "nonexistent")
.collect(Collectors.toSet());
Map getResult = cache.getAll(keys);
System.out.println(" 批量获取结果数: " + getResult.size());
// 批量删除
BatchOperationResult removeResult = cache.removeAll(keys);
System.out.println(" 批量删除成功: " + removeResult.getSuccessful().size());
System.out.println(" 批量删除失败: " + removeResult.getFailed().size());
cache.close();
System.out.println();
}
private static void testEventListener() {
System.out.println("4. 事件监听测试");
MetonaCache cache = new MetonaCache<>();
// 添加监听器
cache.addListener(new CacheListener() {
@Override
public void onEvent(CacheEvent event) {
if (event.getEventType() == CacheEventType.PUT) {
System.out.println(" [监听器] 新增缓存项: " + event.getKey() + " = " + event.getValue());
} else if (event.getEventType() == CacheEventType.GET) {
System.out.println(" [监听器] 获取缓存项: " + event.getKey());
}
}
});
cache.put("eventKey", "eventValue");
String value = cache.get("eventKey");
System.out.println(" 获取到的值: " + value);
cache.close();
System.out.println();
}
private static void testShardedCache() {
System.out.println("5. 分片缓存测试");
CacheConfig config = CacheConfig.custom().setMaxSize(100);
ShardedCache shardedCache = new ShardedCache<>(4, config);
// 测试分片缓存
for (int i = 0; i < 10; i++) {
shardedCache.put("key" + i, "value" + i);
}
System.out.println(" 分片缓存总大小: " + shardedCache.size());
System.out.println(" 分片数量: " + shardedCache.getShards().size());
// 验证数据分布
for (int i = 0; i < 5; i++) {
String value = shardedCache.get("key" + i);
System.out.println(" key" + i + " = " + value);
}
shardedCache.close();
System.out.println();
}
private static void testCacheTemplate() {
System.out.println("6. 缓存模板测试");
CacheTemplate template = new CacheTemplate<>();
// 基本操作
template.put("templateKey", "templateValue");
String value = template.get("templateKey");
System.out.println(" 模板获取值: " + value);
// 批量操作
Map batchData = Map.of(
"template1", "value1",
"template2", "value2"
);
template.warmUp(batchData);
System.out.println(" 模板预热完成,缓存大小: " + template.getCache().size());
template.close();
System.out.println();
}
}
```