Skip to content

Commit a506738

Browse files
committed
缓存
1 parent 5d5172b commit a506738

File tree

11 files changed

+324
-56
lines changed

11 files changed

+324
-56
lines changed

src/main/java/code/cache/CacheHotKey.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package code.cache;
22

3+
import code.cache.db.IDb;
4+
import code.cache.db.SimpleDb;
5+
36
import java.util.concurrent.ExecutorService;
47
import java.util.concurrent.Executors;
58

src/main/java/code/cache/CachePenetrate.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package code.cache;
22

3+
import code.cache.db.IDb;
4+
import code.cache.db.SimpleDb;
5+
36
import java.util.concurrent.ExecutionException;
47

58
/**

src/main/java/code/cache/CacheSnowCrash.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package code.cache;
22

3+
import code.cache.db.IDb;
4+
import code.cache.db.SimpleDb;
35
import code.distribution.lock.DistributedLock;
46
import code.distribution.lock.ZooKeeperLock;
57

src/main/java/code/cache/LRUCache.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,24 @@
1010
* @author zixiao
1111
* @date 2019/2/25
1212
*/
13-
public class LRUCache implements ICache<String, Object>{
13+
public class LRUCache<K, V> implements ICache<K, V>{
1414

1515
private int maxSize;
1616

17-
private Map<String, DoubleLinkNode> map = new HashMap<>();
17+
private Map<K, DoubleLinkNode<K, V>> map = new HashMap<>();
1818

19-
private DoubleLinkNode head;
19+
private DoubleLinkNode<K, V> head;
2020

21-
private DoubleLinkNode tail;
21+
private DoubleLinkNode<K, V> tail;
2222

2323
public LRUCache(int maxSize){
2424
this.maxSize = maxSize;
2525
}
2626

2727
@Override
28-
public Object get(String key) {
28+
public V get(K key) {
2929
if(map.containsKey(key)){
30-
DoubleLinkNode node = map.get(key);
30+
DoubleLinkNode<K, V> node = map.get(key);
3131
if(head != node){
3232
breakLink(node);
3333
addToHead(node);
@@ -95,12 +95,12 @@ private void removeHead(){
9595
}
9696

9797
@Override
98-
public boolean exist(String key) {
98+
public boolean exist(K key) {
9999
return map.containsKey(key);
100100
}
101101

102102
@Override
103-
public Object set(String key, Object value) {
103+
public V set(K key, V value) {
104104
if(map.containsKey(key)){
105105
DoubleLinkNode node = map.get(key);
106106
node.value = value;
@@ -121,12 +121,12 @@ public Object set(String key, Object value) {
121121
}
122122

123123
@Override
124-
public Object set(String key, Object value, int expireSeconds) {
124+
public V set(K key, V value, int expireSeconds) {
125125
throw new UnsupportedOperationException();
126126
}
127127

128128
@Override
129-
public boolean setnx(String key, Object value) {
129+
public boolean setnx(K key, V value) {
130130
if(map.containsKey(key)){
131131
return false;
132132
}
@@ -135,14 +135,14 @@ public boolean setnx(String key, Object value) {
135135
}
136136

137137
@Override
138-
public void expire(String key, int expireSeconds) {
138+
public void expire(K key, int expireSeconds) {
139139
throw new UnsupportedOperationException();
140140
}
141141

142142
@Override
143-
public Object delete(String key) {
143+
public V delete(K key) {
144144
if(map.containsKey(key)){
145-
DoubleLinkNode node = map.get(key);
145+
DoubleLinkNode<K, V> node = map.get(key);
146146
map.remove(key);
147147
if(head != node){
148148
breakLink(node);
@@ -161,17 +161,17 @@ public void stop() {
161161
tail = null;
162162
}
163163

164-
class DoubleLinkNode{
164+
class DoubleLinkNode<K, V>{
165165

166-
private String key;
166+
private K key;
167167

168-
private Object value;
168+
private V value;
169169

170-
private DoubleLinkNode prev;
170+
private DoubleLinkNode<K, V> prev;
171171

172-
private DoubleLinkNode next;
172+
private DoubleLinkNode<K, V> next;
173173

174-
public DoubleLinkNode(String key, Object value) {
174+
public DoubleLinkNode(K key, V value) {
175175
this.key = key;
176176
this.value = value;
177177
}

src/main/java/code/cache/SimpleCache.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void run() {
4141
while (iterator.hasNext()){
4242
Map.Entry<K,Long> entry = iterator.next();
4343
if(entry.getValue() <= System.currentTimeMillis()){
44-
System.out.println("缓存过期移除key:"+entry.getKey());
44+
System.out.println("[DEBUG]Cache expired key:"+entry.getKey());
4545
iterator.remove();
4646
dataMap.remove(entry.getKey());
4747
}

src/main/java/code/cache/SimpleDb.java

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package code.cache;
2+
3+
import code.cache.db.ReadWriteSplitting;
4+
5+
import java.util.Optional;
6+
7+
/**
8+
* 〈数据库,缓存读写顺序〉<p>
9+
写操作的顺序是:
10+
(1)删除cache;
11+
(2)写数据库;
12+
13+
读操作的顺序是:
14+
(1)读cache,如果cache hit则返回;
15+
(2)如果cache miss,则读从库;
16+
(3)读从库后,将数据放回cache;
17+
*
18+
* @author zixiao
19+
* @date 2019/10/11
20+
*/
21+
public class WriteDbReadCache<K, V> {
22+
23+
private ReadWriteSplitting<K, V> db = new ReadWriteSplitting<>();
24+
25+
private ICache<K, Optional<V>> cache = new SimpleCache<>();
26+
27+
/**
28+
* 写操作的顺序是:
29+
(1)删除cache;
30+
(2)写数据库;
31+
* @param key
32+
* @param value
33+
*/
34+
public void write(K key, V value){
35+
cache.delete(key);
36+
db.write(key, value);
37+
}
38+
39+
/**
40+
* 读操作的顺序是:
41+
(1)读cache,如果cache hit则返回;
42+
(2)如果cache miss,则读从库;
43+
(3)读从库后,将数据放回cache;
44+
* @param key
45+
* @return
46+
*/
47+
public V read(K key){
48+
Optional<V> ov = cache.get(key);
49+
if(ov != null){
50+
System.out.printf(">> read cache:");
51+
return ov.get();
52+
}else{
53+
V v = db.read(key);
54+
cache.set(key, Optional.ofNullable(v));
55+
return v;
56+
}
57+
}
58+
59+
public void close(){
60+
cache.stop();
61+
db.close();
62+
}
63+
64+
public static void main(String[] args) throws InterruptedException {
65+
WriteDbReadCache writeDbReadCache = new WriteDbReadCache();
66+
String key = "test";
67+
writeDbReadCache.write(key, System.currentTimeMillis());
68+
69+
Thread.sleep(100);
70+
System.out.println(String.format("%s=>%s", key, writeDbReadCache.read(key)));
71+
72+
System.out.println("-----------------");
73+
74+
writeDbReadCache.write(key, System.currentTimeMillis());
75+
for (int i = 0; i < 5; i++) {
76+
Thread.sleep(300);
77+
System.out.println(String.format("%s=>%s", key, writeDbReadCache.read(key)));
78+
}
79+
80+
writeDbReadCache.close();
81+
}
82+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package code.cache;
1+
package code.cache.db;
22

33
/**
44
* 〈DB〉<p>
@@ -15,4 +15,5 @@ public interface IDb<K, V> {
1515

1616
V remove(K key);
1717

18+
void close();
1819
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package code.cache.db;
2+
3+
import java.util.concurrent.ScheduledExecutorService;
4+
import java.util.concurrent.ScheduledThreadPoolExecutor;
5+
import java.util.concurrent.TimeUnit;
6+
7+
/**
8+
* 〈主从db〉<p>
9+
* 〈功能详细描述〉
10+
*
11+
* @author zixiao
12+
* @date 2019/10/11
13+
*/
14+
public class MasterSlaveDb<K, V> implements IDb<K, V>{
15+
16+
private SimpleDb<K, V> master = new SimpleDb<>();
17+
18+
private SimpleDb<K, V> slave = new SimpleDb<>();
19+
20+
private ScheduledExecutorService dbSync = new ScheduledThreadPoolExecutor(1);
21+
22+
public MasterSlaveDb(){
23+
this(300);
24+
}
25+
26+
public MasterSlaveDb(long syncDelay){
27+
dbSync.scheduleAtFixedRate(new Runnable() {
28+
@Override
29+
public void run() {
30+
slave.getAll().forEach((k, v) -> {
31+
if (master.get(k) == null) {
32+
slave.remove(k);
33+
}
34+
});
35+
master.getAll().forEach((k, v) -> {
36+
slave.put(k, v);
37+
});
38+
}
39+
}, 100, syncDelay/2, TimeUnit.MILLISECONDS);
40+
}
41+
42+
@Override
43+
public V get(K key) {
44+
return slave.get(key);
45+
}
46+
47+
public V getFromMaster(K key) {
48+
return master.get(key);
49+
}
50+
51+
@Override
52+
public V put(K key, V value) {
53+
return master.put(key, value);
54+
}
55+
56+
@Override
57+
public V remove(K key) {
58+
return master.remove(key);
59+
}
60+
61+
@Override
62+
public void close() {
63+
dbSync.shutdown();
64+
}
65+
66+
public static void main(String[] args) throws InterruptedException {
67+
IDb db = new MasterSlaveDb<String, Long>();
68+
String key = "1";
69+
db.put(key, System.currentTimeMillis());
70+
for (int i = 0; i < 5; i++) {
71+
Thread.sleep(100);
72+
System.out.println(String.format("%s=>%s", key, db.get(key)));
73+
}
74+
75+
System.out.println("-----------------");
76+
77+
db.put(key, System.currentTimeMillis());
78+
for (int i = 0; i < 5; i++) {
79+
Thread.sleep(100);
80+
System.out.println(String.format("%s=>%s", key, db.get(key)));
81+
}
82+
83+
db.close();
84+
}
85+
}

0 commit comments

Comments
 (0)