# 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(); } } ```