0%

用Java代码实现本地缓存

要点:

  • 数据存储格式:String-Object
  • 作为工具类所有方法需要static
  • key的删除策略:
    • 定时任务线程定期删除(ScheduledExecutorService)
    • get时手动检测是否过期(懒惰淘汰)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import java.util.concurrent.*;

public class LocalCache {
//启动开始后延迟2秒执行时效策略
private static final int INITIAL_DELAY_TIME = 2;
//执行时效策略间隔时间
private static final int PERIOD_TIME = 2;
//缓存map
private static final ConcurrentHashMap<String, Cache> map;
//执行过期清除的定时任务线程池
private static final ScheduledExecutorService executorService;

static {
map = new ConcurrentHashMap<>();
executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(new TimerTask(), INITIAL_DELAY_TIME, PERIOD_TIME, TimeUnit.SECONDS);
}

/**
* 在get时也需要进行判断
* @param key
* @return
*/
public static Object get(String key) {
Cache cache = map.get(key);
if (cache == null)
return null;
if (cache.getExpire() > 0 && cache.getExpire() < System.currentTimeMillis()) {
remove(key);
return null;
}
return map.get(key).getValue();
}

public static void put(String key, Object value) {
put(key, value, 0);
}

public static void put(String key, Object value, long expire) {
System.out.println("添加缓存,key = " + key + " value = " + value + " ttl = " + expire);
if (expire > 0)
map.put(key, new Cache(value, expire));
else
map.put(key, new Cache(value));
}

public static void remove(String key) {
Cache remove = map.remove(key);
System.out.println("删除了key:" + key + " value:" + remove.getValue());
}

/**
* 定期删除所有过期key
*/
public static void removeAll() {
System.out.println("--------------开始执行定期清除--------------");
for (String key : map.keySet()) {
Cache cache = map.get(key);
long timeMillis = System.currentTimeMillis();
long expire = cache.getExpire();
if (expire > 0 && expire < timeMillis) {
System.out.println("timeMillis = " + timeMillis);
System.out.println("expire = " + expire);
remove(key);
}
}
System.out.println("--------------定期清除结束--------------");
}

/**
* 删除任务
*/
private static class TimerTask implements Runnable {
@Override
public void run() {
try {
removeAll();
} catch (Exception e) {
System.out.println("定期缓存清除异常");
}
}
}

/**
* 缓存对象
*/
private static class Cache {
private Object value;
private long expire = 0;

public Cache(Object value, long expire) {
this.value = value;
this.expire = System.currentTimeMillis() + expire * 1000;;
}

public Cache(Object value) {
this.value = value;
}

public Object getValue() {
return value;
}

public long getExpire() {
return expire;
}
}
}