- 定时删除,每一个key都设置过期时间,每个key都用一个线程跟踪,当这个key过了过期时间,该线程就将这个key删除;但是当key的数量很大时,就会有很多线程,CPU的占用量会非常大
public class DeletePolicy1 {
private static Map<String,String> redis = new HashMap<>();
public static void set(String key, String value, Long timeout) {
redis.put(key, value);
new Thread(new Runnable() {
@Override
public void run() {
long currentTimeMillis = System.currentTimeMillis() + timeout;
while(true) {
if(System.currentTimeMillis() > currentTimeMillis) {
redis.remove(key);
}
}
}
}).start();
}
public static String get(String key) {
return redis.get(key);
}
public static void main(String[] args) {
set("young","xian",5000L);
int i = 1;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string = get("young");
System.out.println("第" + i + "秒得到的值为:" + string);
i++;
}
}
}
- 惰性删除,redis服务器不会主动删除数据,当访问这个key时,redis服务器会先判断这个key有没有过期,如果过期了则删除这个key,并且返回null。缺点是内存占用量大
public class DeletePolicy2 {
private static Map<String,String> redis = new HashMap<>();
private static Map<String,Long> deleteMap = new HashMap<>();
public static void set(String key, String value, Long timeout) {
redis.put(key, value);
long currentTimeMillis = System.currentTimeMillis() + timeout;
deleteMap.put(key, currentTimeMillis);
}
public static String get(String key) {
if(deleteMap.containsKey(key)) {
if(System.currentTimeMillis() > deleteMap.get(key)) {
redis.remove(key);
deleteMap.remove(key);
return null;
}
}
return redis.get(key);
}
public static void main(String[] args) {
set("young","xian",5000L);
int i = 1;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string = get("young");
System.out.println("第" + i + "秒得到的值为:" + string);
i++;
}
}
}
- 定期删除,redis服务器会开启一个线程定期去扫描过期的key,如果扫描到了,就将这个key删除。(可能一些key过期了,但是还是没有扫描到,那么用户依然还可以访问这个key。在内存和CPU上做了一个平衡,但是删除得不及时,实时性差)
public class DeletePolicy {
private static Map<String,String> redis = new HashMap<>();
private static Map<String,Long> dieNews = new HashMap<>();
private static Object lock = new Object();
static {
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Set<String> deletes = new HashSet<>();
if(dieNews.isEmpty()) {
synchronized (lock) {
try {
System.out.println("不存在过期的key,休眠一会儿");
lock.wait();
System.out.println("检查线程启动...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
dieNews.forEach((k,v)->{
if(System.currentTimeMillis() > dieNews.get(k)) {
deletes.add(k);
}
});
for (String key : deletes) {
dieNews.remove(key);
redis.remove(key);
}
}
}
}).start();
}
public static void set(String key, String value,Long timeout) {
redis.put(key, value);
dieNews.put(key, System.currentTimeMillis() + timeout);
synchronized (lock) {
lock.notify();
}
}
public static String get(String key) {
return redis.get(key);
}
public static void main(String[] args) {
set("young","xian",5000L);
int i = 1;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string = get("young");
System.out.println("第" + i + "秒得到的值为:" + string);
i++;
if(i == 8) {
set("young","muxian",5000L);
}
}
}
}
- 惰性删除+定期删除
public class DeletePolicy3 {
private static Map<String,String> redis = new HashMap<>();
private static Map<String,Long> dieNews = new HashMap<>();
private static Object lock = new Object();
static {
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Set<String> deletes = new HashSet<>();
if(dieNews.isEmpty()) {
synchronized (lock) {
try {
System.out.println("不存在过期的key,休眠一会儿");
lock.wait();
System.out.println("检查线程启动...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
dieNews.forEach((k,v)->{
if(System.currentTimeMillis() > dieNews.get(k)) {
deletes.add(k);
}
});
for (String key : deletes) {
dieNews.remove(key);
redis.remove(key);
}
}
}
}).start();
}
public static void set(String key, String value,Long timeout) {
redis.put(key, value);
dieNews.put(key, System.currentTimeMillis() + timeout);
synchronized (lock) {
lock.notify();
}
}
public static String get(String key) {
if(dieNews.containsKey(key)) {
Long time = dieNews.get(key);
if(System.currentTimeMillis() > time) {
dieNews.remove(key);
redis.remove(key);
return null;
}
}
return redis.get(key);
}
public static void main(String[] args) {
set("young","xian",5000L);
int i = 1;
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string = get("young");
System.out.println("第" + i + "秒得到的值为:" + string);
i++;
if(i == 8) {
set("young","muxian",5000L);
}
}
}
}