# sinrycache
**Repository Path**: isinry/sinrycache
## Basic Information
- **Project Name**: sinrycache
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-12-12
- **Last Updated**: 2021-12-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 一、作业内容
动手实现一个Cache对象或组件或服务,带超时淘汰功能。
补充说明:
(0)用Java语言实现,JDK版本任意。其他语言也欢迎交流。
(1)支持多线程。
(2)描述设计过程。
(3)输出性能测试报告。
# 二、设计描述
1)实现内容:缓存操作,锁策略,缓存命中记录器,缓存序列化策略,淘汰策略
2)设计模式:**责任链模式**,使用该模式目的是为了更好的动态扩展策略

## 1. 超时淘汰机制
- 写入缓存时,由淘汰策略存储key的过期时间
- 当写入新的缓存超过负载数量size时,由ExpireLinkedHashMap取出并计算最旧的条目是否过期,过期则删除缓存
## 2. 存储器
存储器使用ConcurrentHashMap作为缓存
# 三、性能测试
> 
> JDK1.8
> 使用parallelStream内置的ForkJoinPool线程池,默认数量20个
### 1. 多线程测试
- 测试代码
```java
@Test
public void test1() {
List list = new ArrayList<>();
for (int i = 1; i <= 1000000; i++) {
list.add(i);
}
System.out.println("写入测试 >>>");
long startTime = System.currentTimeMillis();
list.parallelStream().forEach(i -> {
cache.set("name_" + i, "sinry_" + i);
System.out.println(i);
});
long endTime = System.currentTimeMillis();
long result = endTime - startTime;
System.out.println("写入结果:" + list.size() + "个");
System.out.println("执行耗时:"+result+"ms");
System.out.println("========================");
System.out.println("读取测试 >>>");
long readStartTime = System.currentTimeMillis();
List collect = list.parallelStream().peek(i -> cache.get("name_" + i))
.collect(Collectors.toList());
long readEndTime = System.currentTimeMillis();
long readResult = readEndTime - readStartTime;
System.out.println("读取结果:" + collect.size() + "个");
System.out.println("执行耗时:"+readResult+"ms");
}
```
- 运行结果
```java
写入测试 >>>
写入结果:1000000个
执行耗时:1899ms
========================
读取测试 >>>
读取结果:1000000个
执行耗时:1349ms
```
### 2. 单线程测试
- 测试代码
```java
@Test
public void test1() {
List list = new ArrayList<>();
for (int i = 1; i <= 1000000; i++) {
list.add(i);
}
System.out.println("写入测试 >>>");
long startTime = System.currentTimeMillis();
list.forEach(i -> cache.set("name_" + i, "sinry_" + i));
long endTime = System.currentTimeMillis();
long result = endTime - startTime;
System.out.println("写入结果:" + list.size() + "个");
System.out.println("执行耗时:"+result+"ms");
System.out.println("========================");
System.out.println("读取测试 >>>");
long readStartTime = System.currentTimeMillis();
List collect = list.stream().peek(i -> cache.get("name_" + i))
.collect(Collectors.toList());
long readEndTime = System.currentTimeMillis();
long readResult = readEndTime - readStartTime;
System.out.println("读取结果:" + collect.size() + "个");
System.out.println("执行耗时:"+readResult+"ms");
}
```
- 测试结果
```java
写入测试 >>>
写入结果:1000000个
执行耗时:1581ms
========================
读取测试 >>>
读取结果:1000000个
执行耗时:943ms
```
### 3. 测试总结
- 模拟并发写入和读取测试
- 受限于机器内存,写入大量数据则会内存不足导致OOM
- 多线程测试
- 多线程比单线程慢,是因为M1的单核处理能力要比多核处理快😅
# 四、优缺点
- 优点
- 动态扩展策略,应用层可自由配置策略
- 缺点
- 存储器由hashmap实现,有相对局限性
- 淘汰策略不支持自动到期淘汰,目前只可以读取时计算到期时间,
需要用到定时器处理。
- 随着策略模式的扩展也会对性能有损耗